From 98e96345dff14e227904861d689f5e0248c7fe8b Mon Sep 17 00:00:00 2001 From: Luca Morgado Date: Tue, 1 Oct 2024 16:32:38 +0200 Subject: [PATCH 1/2] updated interpreter error and replaced parseExpr with the appropriate allowed expression --- DEMO/Test/struct.ecla | 9 +++++++++ interpreter/expr.go | 2 +- parser/Parser.go | 16 +++++++++++++++- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/DEMO/Test/struct.ecla b/DEMO/Test/struct.ecla index 35e5642..18e6c03 100644 --- a/DEMO/Test/struct.ecla +++ b/DEMO/Test/struct.ecla @@ -67,3 +67,12 @@ p.printSelf(p); # access embedded struct fields console.println(p.test.test); +# use a struct field in a binary operation +var p2 int = p.x + p.y; +console.println(p2); + +# use a field of a struct field in a binary operation +var p3 string = p.test.test + p.test.test; +console.println(p3); + + diff --git a/interpreter/expr.go b/interpreter/expr.go index 98dd3cd..c7c59bd 100644 --- a/interpreter/expr.go +++ b/interpreter/expr.go @@ -572,7 +572,7 @@ func RunSelectorExpr(expr parser.SelectorExpr, env *Env, Struct eclaType.Type) [ } return []*Bus{NewMainBus(*result)} default: - env.ErrorHandle.HandleError(expr.StartLine(), expr.StartPos(), "struct cannot have filed of type "+prev.GetType(), errorHandler.LevelFatal) + env.ErrorHandle.HandleError(expr.StartLine(), expr.StartPos(), "struct cannot have field of type "+prev.GetType(), errorHandler.LevelFatal) } default: env.ErrorHandle.HandleError(expr.StartLine(), expr.StartPos(), "type "+prev.GetType()+" has no fields", errorHandler.LevelFatal) diff --git a/parser/Parser.go b/parser/Parser.go index 00c4df7..3ff3e34 100644 --- a/parser/Parser.go +++ b/parser/Parser.go @@ -951,7 +951,21 @@ func (p *Parser) ParseSelector(x Expr) Expr { p.HandleFatal("Expected field name after '.'") return nil } - selector := p.ParseExpr() + // check if the field is a function call + var selector Expr + if p.Peek(1).TokenType == lexer.LPAREN { + selector = p.ParseFunctionCallExpr() + } else { + selector = p.ParseVariableAccess() + p.Step() + } + // check if there is a period after the selector to see if it is a selector + if p.CurrentToken.TokenType == lexer.PERIOD { + p.Step() + selectorDepth++ + selector = p.ParseSelector(selector) + selectorDepth-- + } return SelectorExpr{Field: p.CurrentToken, Expr: x, Sel: selector} } From ce67ecc72b44377ab12852c8597b8fb5df0a1628 Mon Sep 17 00:00:00 2001 From: Luca Morgado Date: Wed, 2 Oct 2024 14:48:32 +0200 Subject: [PATCH 2/2] added unit test for the new selector implementation --- parser/Parser_test.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/parser/Parser_test.go b/parser/Parser_test.go index 0f9d4e2..30f5a2a 100644 --- a/parser/Parser_test.go +++ b/parser/Parser_test.go @@ -1335,6 +1335,23 @@ func TestParser_ParseSelector(t *testing.T) { } ok = false + // selector with a function call + resetWithTokens(&par, lexer.Lexer("test.test()")) + par.MultiStep(2) + par.ParseSelector(nil) + if ok { + t.Errorf("ParseSelector() raised an error when it should not") + } + ok = false + // selector used in a binary expression + resetWithTokens(&par, lexer.Lexer("test.test + 1")) + par.MultiStep(2) + par.ParseSelector(nil) + if ok { + t.Errorf("ParseSelector() raised an error when it should not") + } + ok = false + e.RestoreExit() }