From a3116a6613363f303b84f5f704f5e87495d4f3b9 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Tue, 12 Mar 2024 09:50:32 +0100 Subject: fix: force adding a return at end of function This will avoid infinite loops, and is necessary for functions with no returned values. This doesn't remove the need to better check the consistency of return statements in general. --- parser/interpreter_test.go | 1 + parser/parse.go | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/parser/interpreter_test.go b/parser/interpreter_test.go index c3f2909..8f166df 100644 --- a/parser/interpreter_test.go +++ b/parser/interpreter_test.go @@ -97,6 +97,7 @@ func TestFunc(t *testing.T) { {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, b, c int) int {return a+b-c} ; f(7, 1, 3)", res: "5"}, + {src: "var a int; func f() {a = a+2}; f(); a", res: "2"}, }) } diff --git a/parser/parse.go b/parser/parse.go index ffa8102..c13c33d 100644 --- a/parser/parse.go +++ b/parser/parse.go @@ -246,6 +246,15 @@ func (p *Parser) ParseFunc(in Tokens) (out Tokens, err error) { out = append(out, scanner.Token{Id: lang.Grow, Beg: l}) } out = append(out, toks...) + if out[len(out)-1].Id != lang.Return { + // Ensure that a return statment is always added at end of function. + // TODO: detect missing or wrong returns + x, err := p.ParseReturn([]scanner.Token{{Id: lang.Return}}) + if err != nil { + return out, err + } + out = append(out, x...) + } out = append(out, scanner.Token{Id: lang.Label, Str: fname + "_end"}) return out, err } -- cgit v1.2.3 From cb8041b04472059703043b827a79287387c9dd8d Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Tue, 12 Mar 2024 10:03:41 +0100 Subject: fixup --- parser/parse.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/parser/parse.go b/parser/parse.go index c13c33d..547957b 100644 --- a/parser/parse.go +++ b/parser/parse.go @@ -248,8 +248,8 @@ func (p *Parser) ParseFunc(in Tokens) (out Tokens, err error) { out = append(out, toks...) if out[len(out)-1].Id != lang.Return { // Ensure that a return statment is always added at end of function. - // TODO: detect missing or wrong returns - x, err := p.ParseReturn([]scanner.Token{{Id: lang.Return}}) + // TODO: detect missing or wrong returns. + x, err := p.ParseReturn(nil) if err != nil { return out, err } @@ -420,10 +420,12 @@ func (p *Parser) ParseLabel(in Tokens) (out Tokens, err error) { } func (p *Parser) ParseReturn(in Tokens) (out Tokens, err error) { - if len(in) > 1 { + if l := len(in); l > 1 { if out, err = p.ParseExpr(in[1:]); err != nil { return out, err } + } else if l == 0 { + in = Tokens{{Id: lang.Return}} // Implicit return in functions with no return parameters. } // TODO: the function symbol should be already present in the parser context. -- cgit v1.2.3