diff --git a/internal/ast/ast.go b/internal/ast/ast.go index 4787f42..33b6402 100644 --- a/internal/ast/ast.go +++ b/internal/ast/ast.go @@ -11,6 +11,7 @@ var _ Node = (*Program)(nil) var _ Expression = (*IdentifierExpression)(nil) var _ Expression = (*IntegerExpression)(nil) var _ Expression = (*BooleanExpression)(nil) +var _ Expression = (*StringExpression)(nil) var _ Expression = (*IfExpression)(nil) var _ Expression = (*FuncExpression)(nil) var _ Expression = (*CallExpression)(nil) diff --git a/internal/evaluator/evaluator.go b/internal/evaluator/evaluator.go index 9583375..e0690f7 100644 --- a/internal/evaluator/evaluator.go +++ b/internal/evaluator/evaluator.go @@ -53,6 +53,8 @@ func (e *evaluator) Eval(node ast.Node) (object.Object, error) { return object.NewInteger(node.Value), nil case *ast.BooleanExpression: return booleanConv(node.Value), nil + case *ast.StringExpression: + return object.NewString(node.Value), nil case *ast.IfExpression: return e.evalIfExpression(node) case *ast.FuncExpression: diff --git a/internal/evaluator/evaluator_test.go b/internal/evaluator/evaluator_test.go index 8997cbf..6d6a94b 100644 --- a/internal/evaluator/evaluator_test.go +++ b/internal/evaluator/evaluator_test.go @@ -558,6 +558,25 @@ var _ = Describe("Evaluator", func() { }) }) + Context("string object", func() { + It("string expression", func() { + text = ` + "hello world"; + ` + expectedObject := object.NewString("hello world") + expectedErrors := []error{} + + // parse the program + program, errs = p.ParseProgram(text) + Expect(errs).To(Equal(expectedErrors)) + + // evaluate the AST tree + obj, err := e.Eval(program) + Expect(err).To(BeNil()) + Expect(obj).To(Equal(expectedObject)) + }) + }) + Context("if conditionals", func() { It("if condition is truthy", func() { text = ` diff --git a/internal/object/object.go b/internal/object/object.go index 48a4d25..ebda9f3 100644 --- a/internal/object/object.go +++ b/internal/object/object.go @@ -10,6 +10,7 @@ import ( // interface compliance check var _ Object = (*Integer)(nil) var _ Object = (*Boolean)(nil) +var _ Object = (*String)(nil) var _ Object = (*Nil)(nil) var _ Object = (*ReturnValue)(nil) var _ Object = (*Error)(nil) @@ -20,6 +21,7 @@ type ObjectType string var ( INTEGER_OBJ = ObjectType("INTEGER") BOOLEAN_OBJ = ObjectType("BOOLEAN") + STRING_OBJ = ObjectType("STRING") NIL_OBJ = ObjectType("NIL") RETURN_VALUE_OBJ = ObjectType("RETURN_VALUE") ERROR_OBJ = ObjectType("ERROR") @@ -84,6 +86,28 @@ func (b *Boolean) IsTruthy() bool { return b.Value } +type String struct { + Value string +} + +func NewString(value string) *String { + return &String{ + Value: value, + } +} + +func (s *String) Type() ObjectType { + return STRING_OBJ +} + +func (s *String) Inspect() string { + return s.Value +} + +func (s *String) IsTruthy() bool { + return len(s.Value) > 0 +} + // Nil represents the absence of any value type Nil struct{} diff --git a/internal/object/object_test.go b/internal/object/object_test.go index b81c494..5842b0f 100644 --- a/internal/object/object_test.go +++ b/internal/object/object_test.go @@ -66,7 +66,7 @@ var _ = Describe("Object", func() { }) }) - Describe("Boolean", func() { + Describe("Nil", func() { It("false nil object", func() { expectedNilObj := object.NIL obj := object.NewNil() @@ -77,4 +77,34 @@ var _ = Describe("Object", func() { Expect(obj.IsTruthy()).To(Equal(false)) }) }) + + Describe("String", func() { + It("false string object", func() { + var val string = "" + + expectedStringObj := &object.String{ + Value: val, + } + obj := object.NewString(val) + + Expect(obj).To(Equal(expectedStringObj)) + Expect(obj.Inspect()).To(Equal("")) + Expect(obj.Type()).To(Equal(object.STRING_OBJ)) + Expect(obj.IsTruthy()).To(Equal(false)) + }) + + It("truthy string object", func() { + var val string = "hello" + + expectedStringObj := &object.String{ + Value: val, + } + obj := object.NewString(val) + + Expect(obj).To(Equal(expectedStringObj)) + Expect(obj.Inspect()).To(Equal("hello")) + Expect(obj.Type()).To(Equal(object.STRING_OBJ)) + Expect(obj.IsTruthy()).To(Equal(true)) + }) + }) })