From a79e558d825c5b777c95c5e098b01391ee36781e Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Wed, 15 Nov 2023 22:38:46 +0100 Subject: parser: parse struct type declarations Recursive structs and embedded structs are not supported yet. --- parser/type.go | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'parser/type.go') diff --git a/parser/type.go b/parser/type.go index 41bcfe1..f39acea 100644 --- a/parser/type.go +++ b/parser/type.go @@ -19,7 +19,10 @@ const ( ) var ( - missingTypeError = errors.New("Missing type") + InvalidTypeErr = errors.New("invalid type") + MissingTypeErr = errors.New("missing type") + SyntaxErr = errors.New("syntax error") + TypeNotImplementedErr = errors.New("not implemented") ) // ParseTypeExpr parses a list of tokens defining a type expresssion and returns @@ -69,9 +72,32 @@ func (p *Parser) ParseTypeExpr(in Tokens) (typ reflect.Type, err error) { // TODO: selector expression (pkg.type) s, _, ok := p.getSym(in[0].Str, p.scope) if !ok || s.kind != symType { - return nil, fmt.Errorf("invalid type %s", in[0].Str) + return nil, fmt.Errorf("%w: %s", InvalidTypeErr, in[0].Str) } return s.Type, nil + + case lang.Struct: + if len(in) != 2 || in[1].Id != lang.BraceBlock { + return nil, fmt.Errorf("%w: %v", SyntaxErr, in) + } + if in, err = p.Scan(in[1].Block(), false); err != nil { + return nil, err + } + var fields []reflect.StructField + for _, lt := range in.Split(lang.Semicolon) { + types, names, err := p.parseParamTypes(lt, parseTypeType) + if err != nil { + return nil, err + } + for i, name := range names { + fields = append(fields, reflect.StructField{Name: "X" + name, Type: types[i]}) + // TODO: handle embedded fields + } + } + return reflect.StructOf(fields), nil + + default: + return nil, fmt.Errorf("%w: %v", TypeNotImplementedErr, in[0].Name()) } return typ, err } @@ -93,7 +119,7 @@ func (p *Parser) parseParamTypes(in Tokens, flag typeFlag) (types []reflect.Type t = t[1:] if len(t) == 0 { if len(types) == 0 { - return nil, nil, missingTypeError + return nil, nil, MissingTypeErr } // Type was ommitted, apply the previous one from the right. types = append([]reflect.Type{types[0]}, types...) -- cgit v1.2.3