diff --git a/parser/ast.go b/parser/ast.go index b5053bbb8098db2f8552c8169720a7cced2f4814..57c49483620086c8236b6b73bc05fa6fa60b4d44 100644 --- a/parser/ast.go +++ b/parser/ast.go @@ -164,6 +164,7 @@ const ( Int64Type ListType MapType + NotEvaluatedType ) func (t Type) String() string { @@ -178,6 +179,8 @@ func (t Type) String() string { return "list" case MapType: return "map" + case NotEvaluatedType: + return "notevaluated" default: panic(fmt.Errorf("Unknown type %d", t)) } @@ -476,6 +479,29 @@ func (c Comment) Text() string { return string(buf) } +type NotEvaluated struct { + Position scanner.Position +} + +func (n NotEvaluated) Copy() Expression { + return NotEvaluated{Position: n.Position} +} + +func (n NotEvaluated) String() string { + return "Not Evaluated" +} + +func (n NotEvaluated) Type() Type { + return NotEvaluatedType +} + +func (n NotEvaluated) Eval() Expression { + return NotEvaluated{Position: n.Position} +} + +func (n NotEvaluated) Pos() scanner.Position { return n.Position } +func (n NotEvaluated) End() scanner.Position { return n.Position } + func endPos(pos scanner.Position, n int) scanner.Position { pos.Offset += n pos.Column += n diff --git a/parser/parser.go b/parser/parser.go index cb8624616042f4daa965e25ba4795aaae16050e6..6ae5df30d2d3ec0ae7bb2c6bd2e9ce450ce256e0 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -484,6 +484,8 @@ func (p *parser) parseVariable() Expression { } value = assignment.Value } + } else { + value = &NotEvaluated{} } value = &Variable{ Name: text, diff --git a/parser/parser_test.go b/parser/parser_test.go index 6377dc103c3b878d5e56cdffb251865f90e1935c..70151adc904bc2b40a216304623324f019b613a0 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -1122,3 +1122,24 @@ func TestParserEndPos(t *testing.T) { } } } + +func TestParserNotEvaluated(t *testing.T) { + // When parsing without evaluation, create variables correctly + scope := NewScope(nil) + input := "FOO=abc\n" + _, errs := Parse("", bytes.NewBufferString(input), scope) + if errs != nil { + t.Errorf("unexpected errors:") + for _, err := range errs { + t.Errorf(" %s", err) + } + t.FailNow() + } + assignment, found := scope.Get("FOO") + if !found { + t.Fatalf("Expected to find FOO after parsing %s", input) + } + if s := assignment.String(); strings.Contains(s, "PANIC") { + t.Errorf("Attempt to print FOO returned %s", s) + } +}