From 3bf75a780010ff89493ffed499d7c7abc9cfa47c Mon Sep 17 00:00:00 2001 From: kmichaelk <130953568+kmichaelk@users.noreply.github.com> Date: Fri, 13 Sep 2024 23:16:13 +0300 Subject: [PATCH] Support for dynamic templates --- ttcn3/syntax/nodes.go | 7 ++++ ttcn3/syntax/nodes_gen.go | 67 +++++++++++++++++++++++++++++++++++++++ ttcn3/syntax/parser.go | 21 ++++++++++-- 3 files changed, 93 insertions(+), 2 deletions(-) diff --git a/ttcn3/syntax/nodes.go b/ttcn3/syntax/nodes.go index aba8b4ba..55954903 100644 --- a/ttcn3/syntax/nodes.go +++ b/ttcn3/syntax/nodes.go @@ -314,6 +314,12 @@ type ( X Expr // Template expression } + // A DynamicExpr represents a "@dynamic" expression. + DynamicExpr struct { + Tok Token // Position of "dynamic" + Body *BlockStmt // Template body + } + // A DefKindExpr represents a definition kind expression, used by imports // and with-attributes. DefKindExpr struct { @@ -360,6 +366,7 @@ func (x *RegexpExpr) exprNode() {} func (x *PatternExpr) exprNode() {} func (x *DecmatchExpr) exprNode() {} func (x *DecodedExpr) exprNode() {} +func (x *DynamicExpr) exprNode() {} func (x *DefKindExpr) exprNode() {} func (x *ExceptExpr) exprNode() {} diff --git a/ttcn3/syntax/nodes_gen.go b/ttcn3/syntax/nodes_gen.go index cd56c75d..bb5ce218 100644 --- a/ttcn3/syntax/nodes_gen.go +++ b/ttcn3/syntax/nodes_gen.go @@ -2090,6 +2090,73 @@ func (n *DoWhileStmt) End() int { return -1 } +func (n *DynamicExpr) FirstTok() Token { + switch { + + case n.Tok != nil: + return n.Tok + + case n.Body != nil: + return n.Body.FirstTok() + + default: + return nil + } +} + +func (n *DynamicExpr) LastTok() Token { + switch { + + case n.Body != nil: + return n.Body.LastTok() + + case n.Tok != nil: + return n.Tok + + default: + return nil + } +} + +func (n *DynamicExpr) Children() []Node { + ret := make([]Node, 0, 2) + + if n.Tok != nil { + ret = append(ret, n.Tok) + } + + if n.Body != nil { + ret = append(ret, n.Body) + } + + return ret +} + +func (n *DynamicExpr) Inspect(f func(Node) bool) { + + if c := n.Body; c != nil { + if f(c) { + c.Inspect(f) + } + f(nil) + } + +} + +func (n *DynamicExpr) Pos() int { + if tok := n.FirstTok(); tok != nil { + return tok.Pos() + } + return -1 +} + +func (n *DynamicExpr) End() int { + if tok := n.LastTok(); tok != nil { + return tok.End() + } + return -1 +} + func (n *EnumSpec) FirstTok() Token { switch { diff --git a/ttcn3/syntax/parser.go b/ttcn3/syntax/parser.go index 3605eb3e..8208de90 100644 --- a/ttcn3/syntax/parser.go +++ b/ttcn3/syntax/parser.go @@ -817,7 +817,10 @@ func (p *parser) parseOperand() Expr { return p.parseCallDecmatch() case MODIF: - return p.parseDecodedModifier() + return p.parseModifier() + + case VALUE: + return p.parseIdent() default: p.errorExpected("operand") @@ -897,6 +900,13 @@ func (p *parser) parseCallDecmatch() *DecmatchExpr { return c } +func (p *parser) parseModifier() Expr { + if p.peek(1).String() == "@dynamic" { + return p.parseDynamicModifier() + } + return p.parseDecodedModifier() +} + func (p *parser) parseDecodedModifier() *DecodedExpr { d := new(DecodedExpr) d.Tok = p.expect(MODIF) @@ -911,6 +921,13 @@ func (p *parser) parseDecodedModifier() *DecodedExpr { return d } +func (p *parser) parseDynamicModifier() *DynamicExpr { + d := new(DynamicExpr) + d.Tok = p.expect(MODIF) + d.Body = p.parseBlockStmt() + return d +} + func (p *parser) parseSelectorExpr(x Expr) *SelectorExpr { return &SelectorExpr{X: x, Dot: p.consume(), Sel: p.parseRef()} } @@ -1015,7 +1032,7 @@ func (p *parser) parseIdent() *Ident { switch p.tok { case UNIVERSAL: return p.parseUniversalCharstring() - case IDENT, ADDRESS, ALIVE, CHARSTRING, CONTROL, TO, FROM, CREATE: + case IDENT, ADDRESS, ALIVE, CHARSTRING, CONTROL, TO, FROM, CREATE, VALUE: return p.make_use(p.consume()) default: p.expect(IDENT) // use expect() error handling