summaryrefslogtreecommitdiff
path: root/parser/decl.go
diff options
context:
space:
mode:
authorMarc Vertes <mvertes@free.fr>2023-11-10 22:08:46 +0100
committerMarc Vertes <mvertes@free.fr>2023-11-10 22:08:46 +0100
commitbec71a19e7d7cd0847d1cfa6ef2110d7301fcdd1 (patch)
tree7d977e9ad86c119603db88d3fdbf689a845ff8e5 /parser/decl.go
parent5220ccb741c7f3688731d3b3df6e5e851f50f5c5 (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.go65
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
+}