diff options
| author | Marc Vertes <mvertes@free.fr> | 2023-11-10 22:08:46 +0100 |
|---|---|---|
| committer | Marc Vertes <mvertes@free.fr> | 2023-11-10 22:08:46 +0100 |
| commit | bec71a19e7d7cd0847d1cfa6ef2110d7301fcdd1 (patch) | |
| tree | 7d977e9ad86c119603db88d3fdbf689a845ff8e5 /parser/decl.go | |
| parent | 5220ccb741c7f3688731d3b3df6e5e851f50f5c5 (diff) | |
parser: implement support for var declarations
The full Go syntax is supported, blocks or line,
mutiple comma separated variables, assignments.
In local and global frame.
Diffstat (limited to 'parser/decl.go')
| -rw-r--r-- | parser/decl.go | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/parser/decl.go b/parser/decl.go new file mode 100644 index 0000000..fa07c17 --- /dev/null +++ b/parser/decl.go @@ -0,0 +1,65 @@ +package parser + +import ( + "errors" + "log" + "strings" + + "github.com/gnolang/parscan/lang" + "github.com/gnolang/parscan/scanner" +) + +func (p *Parser) ParseVar(in Tokens) (out Tokens, err error) { + if len(in) < 1 { + return out, errors.New("missing expression") + } + if in[1].Id != lang.ParenBlock { + return p.parseVarLine(in[1:]) + } + if in, err = p.Scan(in[1].Block(), false); err != nil { + return out, err + } + for _, lt := range in.Split(lang.Semicolon) { + if lt, err = p.parseVarLine(lt); err != nil { + return out, err + } + out = append(out, lt...) + } + return out, err +} + +func (p *Parser) parseVarLine(in Tokens) (out Tokens, err error) { + decl := in + var assign Tokens + if i := decl.Index(lang.Assign); i >= 0 { + assign = decl[i+1:] + decl = decl[:i] + } + var vars []string + if _, vars, err = p.parseParamTypes(decl, parseTypeVar); err != nil { + if errors.Is(err, missingTypeError) { + for _, lt := range decl.Split(lang.Comma) { + vars = append(vars, lt[0].Str) + // TODO: compute type from rhs + p.addSym(unsetAddr, strings.TrimPrefix(p.scope+"/"+lt[0].Str, "/"), nil, symVar, nil, false) + } + } else { + return out, err + } + } + values := assign.Split(lang.Comma) + if len(values) == 1 && len(values[0]) == 0 { + values = nil + } + log.Println("ParseVar:", vars, values, len(values)) + for i, v := range values { + if v, err = p.ParseExpr(v); err != nil { + return out, err + } + out = append(out, v...) + out = append(out, + scanner.Token{Id: lang.Ident, Str: vars[i]}, + scanner.Token{Id: lang.Assign}) + } + return out, err +} |
