From 36149e5828df1bb35e06905c65f007dd5869aaec Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Fri, 13 Oct 2023 18:32:13 +0200 Subject: parser: include absolute paths in symbols --- lang/token.go | 2 -- parser/compiler.go | 20 +++++--------------- parser/interpreter_test.go | 2 +- parser/parse.go | 20 ++++++++++++-------- parser/symbol.go | 6 ++---- parser/type.go | 8 ++++---- 6 files changed, 24 insertions(+), 34 deletions(-) diff --git a/lang/token.go b/lang/token.go index 3a980a4..5347504 100644 --- a/lang/token.go +++ b/lang/token.go @@ -101,8 +101,6 @@ const ( CallX Label JumpFalse - Enter // entering in function context - Exit // exiting from function context ) func (t TokenId) IsKeyword() bool { return t >= Break && t <= Var } diff --git a/parser/compiler.go b/parser/compiler.go index 68f0596..5d07ae5 100644 --- a/parser/compiler.go +++ b/parser/compiler.go @@ -44,12 +44,9 @@ func (c *Compiler) AddSym(name string, value any) int { func (c *Compiler) Codegen(tokens Tokens) (err error) { fixList := Tokens{} - function := []string{""} - log.Println("Codegen tokens:", tokens) for i, t := range tokens { - scope := function[len(function)-1] switch t.Id { case lang.Int: n, err := strconv.Atoi(t.Str) @@ -91,16 +88,9 @@ func (c *Compiler) Codegen(tokens Tokens) (err error) { c.addSym(l, st.Str, nil, symVar, nil, false) c.Emit(int64(st.Pos), vm.Assign, int64(l)) - case lang.Enter: - // TODO: merge with label ? - function = append(function, t.Str[6:]) - - case lang.Exit: - function = function[:len(function)-1] - case lang.Assign: st := tokens[i-1] - s, _, ok := c.getSym(st.Str, scope) + s, ok := c.symbols[st.Str] if !ok { return fmt.Errorf("symbol not found: %s", st.Str) } @@ -120,7 +110,7 @@ func (c *Compiler) Codegen(tokens Tokens) (err error) { continue } } - s, _, ok := c.getSym(t.Str, scope) + s, ok := c.symbols[t.Str] if !ok { return fmt.Errorf("symbol not found: %s", t.Str) } @@ -132,8 +122,8 @@ func (c *Compiler) Codegen(tokens Tokens) (err error) { case lang.Label: // If the label is a function, the symbol already exists - s, _, ok := c.getSym(t.Str, scope) lc := len(c.Code) + s, ok := c.symbols[t.Str] if ok { s.value = lc if s.kind == symFunc { @@ -153,7 +143,7 @@ func (c *Compiler) Codegen(tokens Tokens) (err error) { case lang.JumpFalse: label := t.Str[10:] i := 0 - if s, _, ok := c.getSym(label, scope); !ok { + if s, ok := c.symbols[label]; !ok { // t.Beg contains the position in code which needs to be fixed. t.Beg = len(c.Code) fixList = append(fixList, t) @@ -165,7 +155,7 @@ func (c *Compiler) Codegen(tokens Tokens) (err error) { case lang.Goto: label := t.Str[5:] i := 0 - if s, _, ok := c.getSym(label, scope); !ok { + if s, ok := c.symbols[label]; !ok { t.Beg = len(c.Code) fixList = append(fixList, t) } else { diff --git a/parser/interpreter_test.go b/parser/interpreter_test.go index 7daec1a..7d676d4 100644 --- a/parser/interpreter_test.go +++ b/parser/interpreter_test.go @@ -63,7 +63,7 @@ func TestFunc(t *testing.T) { {src: "func f(a int) int {return a+2}; 7 - f(3)", res: "2"}, {src: "func f(a int) int {return a+2}; f(5) - f(3)", res: "2"}, {src: "func f(a int) int {return a+2}; f(3) - 2", res: "3"}, - {src: "func f(a int, b int, c int) int {return a+b-c} ; f(7, 1, 3)", res: "5"}, + {src: "func f(a, b, c int) int {return a+b-c} ; f(7, 1, 3)", res: "5"}, }) } diff --git a/parser/parse.go b/parser/parse.go index 4ccb151..c51a73b 100644 --- a/parser/parse.go +++ b/parser/parse.go @@ -208,10 +208,8 @@ func (p *Parser) ParseFunc(in Tokens) (out Tokens, err error) { }() out = Tokens{ - {Id: lang.Enter, Str: "enter " + p.scope}, {Id: lang.Goto, Str: "goto " + fname + "_end"}, // Skip function definition. - {Id: lang.Label, Pos: in[0].Pos, Str: fname}, - } + {Id: lang.Label, Pos: in[0].Pos, Str: fname}} bi := in.Index(lang.BraceBlock) if bi < 0 { @@ -231,10 +229,7 @@ func (p *Parser) ParseFunc(in Tokens) (out Tokens, err error) { return out, err } out = append(out, toks...) - out = append(out, - scanner.Token{Id: lang.Label, Str: fname + "_end"}, - scanner.Token{Id: lang.Exit}, - ) + out = append(out, scanner.Token{Id: lang.Label, Str: fname + "_end"}) log.Println("symbols", p.symbols) return out, err } @@ -325,7 +320,16 @@ func (p *Parser) ParseExpr(in Tokens) (out Tokens, err error) { t := in[i] // temporary assumptions: binary operators, returning 1 value switch t.Id { - case lang.Ident, lang.Int, lang.String: + case lang.Ident: + // resolve symbol if not a selector rhs. + // TODO: test for selector expr. + _, sc, ok := p.getSym(t.Str, p.scope) + if ok && sc != "" { + t.Str = sc + "/" + t.Str + } + out = append(out, t) + vl++ + case lang.Int, lang.String: out = append(out, t) vl++ case lang.Define, lang.Add, lang.Sub, lang.Assign, lang.Equal, lang.Less: diff --git a/parser/symbol.go b/parser/symbol.go index 9975c24..f83ec4e 100644 --- a/parser/symbol.go +++ b/parser/symbol.go @@ -34,14 +34,12 @@ func (p *Parser) addSym(i int, name string, v any, k symKind, t reflect.Type, lo // getSym searches for an existing symbol starting from the deepest scope. func (p *Parser) getSym(name, scope string) (sym *symbol, sc string, ok bool) { for { - if sym, ok = p.symbols[scope+name]; ok { + if sym, ok = p.symbols[scope+"/"+name]; ok { return sym, scope, ok } - scope = strings.TrimSuffix(scope, "/") i := strings.LastIndex(scope, "/") if i == -1 { - scope = "" - break + i = 0 } if scope = scope[:i]; scope == "" { break diff --git a/parser/type.go b/parser/type.go index 77ccc6e..4858d75 100644 --- a/parser/type.go +++ b/parser/type.go @@ -84,9 +84,9 @@ func (p *Parser) parseParamTypes(in Tokens, arg bool) (types []reflect.Type, err // Type was ommitted, apply the previous one from the right. types = append([]reflect.Type{types[0]}, types...) if arg { - p.addSym(-i-2, p.scope+param, nil, symVar, types[0], true) + p.addSym(-i-2, p.scope+"/"+param, nil, symVar, types[0], true) } else { - p.addSym(i, p.scope+param, nil, symVar, types[0], true) + p.addSym(i, p.scope+"/"+param, nil, symVar, types[0], true) } continue } @@ -97,9 +97,9 @@ func (p *Parser) parseParamTypes(in Tokens, arg bool) (types []reflect.Type, err } if param != "" { if arg { - p.addSym(-i-2, p.scope+param, nil, symVar, typ, true) + p.addSym(-i-2, p.scope+"/"+param, nil, symVar, typ, true) } else { - p.addSym(i, p.scope+param, nil, symVar, typ, true) + p.addSym(i, p.scope+"/"+param, nil, symVar, typ, true) } } types = append([]reflect.Type{typ}, types...) -- cgit v1.2.3