commit c887ec01da2d32fb90c22dd84fe104ce5d6fa624
parent 74f2a1ec1374f47939afe92253630cacb116eec5
Author: bsandro <email@bsandro.tech>
Date: Sun, 26 Jun 2022 23:46:50 +0300
Strings eval
Diffstat:
6 files changed, 57 insertions(+), 0 deletions(-)
diff --git a/ast/ast.go b/ast/ast.go
@@ -265,3 +265,16 @@ func (ce *CallExpression) String() string {
out.WriteString(")")
return out.String()
}
+
+type StringLiteral struct {
+ Token token.Token
+ Value string
+}
+
+func (sl *StringLiteral) expressionNode() {}
+func (sl *StringLiteral) TokenLiteral() string {
+ return sl.Token.Literal
+}
+func (sl *StringLiteral) String() string {
+ return sl.Token.Literal
+}
diff --git a/eval/eval.go b/eval/eval.go
@@ -89,6 +89,8 @@ func Eval(node ast.Node, ctx *object.Context) object.Object {
return args[0]
}
return applyFunction(fn, args)
+ case *ast.StringLiteral:
+ return &object.String{Value: node.Value}
}
return nil
}
diff --git a/eval/eval_test.go b/eval/eval_test.go
@@ -228,3 +228,15 @@ func TestFunctionApplication(t *testing.T) {
testIntegerObject(t, testEval(tt.input), tt.expected)
}
}
+
+func TestStringLiteral(t *testing.T) {
+ input := `"ehlo world"`
+ evaluated := testEval(input)
+ str, ok := evaluated.(*object.String)
+ if !ok {
+ t.Fatalf("object is not a string")
+ }
+ if str.Value != "ehlo world" {
+ t.Errorf("String has wrong value: %s", str.Value)
+ }
+}
diff --git a/object/object.go b/object/object.go
@@ -16,6 +16,7 @@ const (
RETURN_VALUE_OBJ = "RETURN_VALUE"
ERROR_OBJ = "ERROR"
FUNCTION_OBJ = "FUNCTION"
+ STRING_OBJ = "STRING"
)
type Object interface {
@@ -76,3 +77,10 @@ func (f *Function) Inspect() string {
out.WriteString("\n}")
return out.String()
}
+
+type String struct {
+ Value string
+}
+
+func (s *String) Type() ObjectType { return STRING_OBJ }
+func (s *String) Inspect() string { return s.Value }
diff --git a/parser/parser.go b/parser/parser.go
@@ -78,6 +78,8 @@ func New(l *lexer.Lexer) *Parser {
p.registerPrefix(token.FUNCTION, p.parseFunctionLiteral)
p.registerInfix(token.LPAREN, p.parseCallExpression)
+ p.registerPrefix(token.STRING, p.parseStringLiteral)
+
return p
}
@@ -368,3 +370,7 @@ func (p *Parser) parseCallArguments() []ast.Expression {
}
return args
}
+
+func (p *Parser) parseStringLiteral() ast.Expression {
+ return &ast.StringLiteral{Token: p.curToken, Value: p.curToken.Literal}
+}
diff --git a/parser/parser_test.go b/parser/parser_test.go
@@ -571,3 +571,19 @@ func TestCallParametersParsing(t *testing.T) {
testInfixExpression(t, expr.Arguments[1], 2, "*", 3)
testInfixExpression(t, expr.Arguments[2], 4, "+", 5)
}
+
+func TestStringLiteralExpression(t *testing.T) {
+ input := `"ehlo world";`
+ l := lexer.New(input)
+ p := New(l)
+ prg := p.ParseProgram()
+ checkParserErrors(t, p)
+ statement := prg.Statements[0].(*ast.ExpressionStatement)
+ literal, ok := statement.Expression.(*ast.StringLiteral)
+ if !ok {
+ t.Fatalf("expression is not string literal")
+ }
+ if literal.Value != "ehlo world" {
+ t.Errorf("literal string value is wrong")
+ }
+}