Refactor Type to be an int
Some checks failed
Publish Image / publish (push) Waiting to run
Test / build (push) Waiting to run
Build / build (push) Has been cancelled

This commit is contained in:
Chuck Smith
2024-03-29 11:01:15 -04:00
parent f65d7bfb1c
commit 12d43c9835
58 changed files with 164 additions and 132 deletions

View File

@@ -41,7 +41,7 @@ func (p *Program) String() string {
var s strings.Builder var s strings.Builder
for _, stmt := range p.Statements { for _, stmt := range p.Statements {
s.WriteString(fmt.Sprintf("%s\n", stmt.String())) s.WriteString(stmt.String())
} }
return s.String() return s.String()

View File

@@ -10,7 +10,7 @@ func Abs(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"abs", args, "abs", args,
typing.ExactArgs(1), typing.ExactArgs(1),
typing.WithTypes(object.INTEGER_OBJ), typing.WithTypes(object.IntegerType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -11,7 +11,7 @@ func Accept(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"accept", args, "accept", args,
typing.ExactArgs(1), typing.ExactArgs(1),
typing.WithTypes(object.INTEGER_OBJ), typing.WithTypes(object.IntegerType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -12,7 +12,7 @@ func Assert(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"assert", args, "assert", args,
typing.ExactArgs(2), typing.ExactArgs(2),
typing.WithTypes(object.BOOLEAN_OBJ, object.STRING_OBJ), typing.WithTypes(object.BooleanType, object.StringType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -12,7 +12,7 @@ func Bin(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"bin", args, "bin", args,
typing.ExactArgs(1), typing.ExactArgs(1),
typing.WithTypes(object.INTEGER_OBJ), typing.WithTypes(object.IntegerType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -11,7 +11,7 @@ func Bind(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"bind", args, "bind", args,
typing.ExactArgs(2), typing.ExactArgs(2),
typing.WithTypes(object.INTEGER_OBJ, object.INTEGER_OBJ), typing.WithTypes(object.IntegerType, object.IntegerType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -11,7 +11,7 @@ func Chr(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"chr", args, "chr", args,
typing.ExactArgs(1), typing.ExactArgs(1),
typing.WithTypes(object.INTEGER_OBJ), typing.WithTypes(object.IntegerType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -11,7 +11,7 @@ func Close(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"close", args, "close", args,
typing.ExactArgs(1), typing.ExactArgs(1),
typing.WithTypes(object.INTEGER_OBJ), typing.WithTypes(object.IntegerType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -11,7 +11,7 @@ func Connect(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"connect", args, "connect", args,
typing.ExactArgs(2), typing.ExactArgs(2),
typing.WithTypes(object.INTEGER_OBJ, object.STRING_OBJ), typing.WithTypes(object.IntegerType, object.StringType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -10,7 +10,7 @@ func Divmod(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"divmod", args, "divmod", args,
typing.ExactArgs(2), typing.ExactArgs(2),
typing.WithTypes(object.INTEGER_OBJ, object.INTEGER_OBJ), typing.WithTypes(object.IntegerType, object.IntegerType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -10,7 +10,7 @@ func Exit(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"exit", args, "exit", args,
typing.RangeOfArgs(0, 1), typing.RangeOfArgs(0, 1),
typing.WithTypes(object.INTEGER_OBJ), typing.WithTypes(object.IntegerType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -15,7 +15,7 @@ func FFI(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"ffi", args, "ffi", args,
typing.ExactArgs(2), typing.ExactArgs(2),
typing.WithTypes(object.STRING_OBJ, object.STRING_OBJ), typing.WithTypes(object.StringType, object.StringType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -23,7 +23,7 @@ func Find(args ...object.Object) object.Object {
if haystack, ok := args[0].(*object.String); ok { if haystack, ok := args[0].(*object.String); ok {
if err := typing.Check( if err := typing.Check(
"find", args, "find", args,
typing.WithTypes(object.STRING_OBJ, object.STRING_OBJ), typing.WithTypes(object.StringType, object.StringType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }
@@ -46,7 +46,7 @@ func Find(args ...object.Object) object.Object {
} }
return newError( return newError(
"TypeError: find() expected argument #1 to be `array` or `str` got `%s`", "TypeError: find() expected argument #1 to be `array` or `str` got `%d`",
args[0].Type(), args[0].Type(),
) )
} }

View File

@@ -10,7 +10,7 @@ func First(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"first", args, "first", args,
typing.ExactArgs(1), typing.ExactArgs(1),
typing.WithTypes(object.ARRAY_OBJ), typing.WithTypes(object.ArrayType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -12,7 +12,7 @@ func Hex(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"hex", args, "hex", args,
typing.ExactArgs(1), typing.ExactArgs(1),
typing.WithTypes(object.INTEGER_OBJ), typing.WithTypes(object.IntegerType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -14,7 +14,7 @@ func Input(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"input", args, "input", args,
typing.RangeOfArgs(0, 1), typing.RangeOfArgs(0, 1),
typing.WithTypes(object.STRING_OBJ), typing.WithTypes(object.StringType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -11,7 +11,7 @@ func Join(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"join", args, "join", args,
typing.ExactArgs(2), typing.ExactArgs(2),
typing.WithTypes(object.ARRAY_OBJ, object.STRING_OBJ), typing.WithTypes(object.ArrayType, object.StringType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -10,7 +10,7 @@ func Last(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"last", args, "last", args,
typing.ExactArgs(1), typing.ExactArgs(1),
typing.WithTypes(object.ARRAY_OBJ), typing.WithTypes(object.ArrayType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -11,7 +11,7 @@ func Listen(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"listen", args, "listen", args,
typing.ExactArgs(2), typing.ExactArgs(2),
typing.WithTypes(object.INTEGER_OBJ, object.INTEGER_OBJ), typing.WithTypes(object.IntegerType, object.IntegerType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -11,7 +11,7 @@ func Lower(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"lower", args, "lower", args,
typing.ExactArgs(1), typing.ExactArgs(1),
typing.WithTypes(object.STRING_OBJ), typing.WithTypes(object.StringType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -11,7 +11,7 @@ func Max(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"max", args, "max", args,
typing.ExactArgs(1), typing.ExactArgs(1),
typing.WithTypes(object.ARRAY_OBJ), typing.WithTypes(object.ArrayType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }
@@ -23,7 +23,7 @@ func Max(args ...object.Object) object.Object {
if i, ok := e.(*object.Integer); ok { if i, ok := e.(*object.Integer); ok {
xs = append(xs, int(i.Value)) xs = append(xs, int(i.Value))
} else { } else {
return newError("item #%d not an `int` got=%s", n, e.Type()) return newError("item #%d not an `int` got=%d", n, e.Type())
} }
} }
sort.Ints(xs) sort.Ints(xs)

View File

@@ -11,7 +11,7 @@ func Min(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"min", args, "min", args,
typing.ExactArgs(1), typing.ExactArgs(1),
typing.WithTypes(object.ARRAY_OBJ), typing.WithTypes(object.ArrayType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }
@@ -23,7 +23,7 @@ func Min(args ...object.Object) object.Object {
if i, ok := e.(*object.Integer); ok { if i, ok := e.(*object.Integer); ok {
xs = append(xs, int(i.Value)) xs = append(xs, int(i.Value))
} else { } else {
return newError("item #%d not an `int` got=%s", n, e.Type()) return newError("item #%d not an `int` got=%d", n, e.Type())
} }
} }
sort.Ints(xs) sort.Ints(xs)

View File

@@ -12,7 +12,7 @@ func Oct(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"oct", args, "oct", args,
typing.ExactArgs(1), typing.ExactArgs(1),
typing.WithTypes(object.INTEGER_OBJ), typing.WithTypes(object.IntegerType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -55,7 +55,7 @@ func Open(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"open", args, "open", args,
typing.RangeOfArgs(1, 2), typing.RangeOfArgs(1, 2),
typing.WithTypes(object.STRING_OBJ, object.STRING_OBJ), typing.WithTypes(object.StringType, object.StringType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -10,7 +10,7 @@ func Ord(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"ord", args, "ord", args,
typing.ExactArgs(1), typing.ExactArgs(1),
typing.WithTypes(object.STRING_OBJ), typing.WithTypes(object.StringType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -10,7 +10,7 @@ func Pop(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"pop", args, "pop", args,
typing.ExactArgs(1), typing.ExactArgs(1),
typing.WithTypes(object.ARRAY_OBJ), typing.WithTypes(object.ArrayType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -22,7 +22,7 @@ func Pow(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"pow", args, "pow", args,
typing.ExactArgs(2), typing.ExactArgs(2),
typing.WithTypes(object.INTEGER_OBJ, object.INTEGER_OBJ), typing.WithTypes(object.IntegerType, object.IntegerType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -11,7 +11,7 @@ func Print(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"print", args, "print", args,
typing.MinimumArgs(1), typing.MinimumArgs(1),
typing.WithTypes(object.STRING_OBJ), typing.WithTypes(object.StringType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -10,7 +10,7 @@ func Push(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"push", args, "push", args,
typing.ExactArgs(2), typing.ExactArgs(2),
typing.WithTypes(object.ARRAY_OBJ), typing.WithTypes(object.ArrayType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -14,7 +14,7 @@ func Read(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"read", args, "read", args,
typing.RangeOfArgs(1, 2), typing.RangeOfArgs(1, 2),
typing.WithTypes(object.INTEGER_OBJ, object.INTEGER_OBJ), typing.WithTypes(object.IntegerType, object.IntegerType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -11,7 +11,7 @@ func ReadFile(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"readfile", args, "readfile", args,
typing.ExactArgs(1), typing.ExactArgs(1),
typing.WithTypes(object.STRING_OBJ), typing.WithTypes(object.StringType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -10,7 +10,7 @@ func Rest(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"rest", args, "rest", args,
typing.ExactArgs(1), typing.ExactArgs(1),
typing.WithTypes(object.ARRAY_OBJ), typing.WithTypes(object.ArrayType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -10,7 +10,7 @@ func Reversed(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"reversed", args, "reversed", args,
typing.ExactArgs(1), typing.ExactArgs(1),
typing.WithTypes(object.ARRAY_OBJ), typing.WithTypes(object.ArrayType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -11,7 +11,7 @@ func Seek(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"seek", args, "seek", args,
typing.RangeOfArgs(1, 3), typing.RangeOfArgs(1, 3),
typing.WithTypes(object.INTEGER_OBJ, object.INTEGER_OBJ, object.INTEGER_OBJ), typing.WithTypes(object.IntegerType, object.IntegerType, object.IntegerType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -12,7 +12,7 @@ func Socket(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"socket", args, "socket", args,
typing.ExactArgs(1), typing.ExactArgs(1),
typing.WithTypes(object.STRING_OBJ), typing.WithTypes(object.StringType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -11,7 +11,7 @@ func Sorted(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"sort", args, "sort", args,
typing.ExactArgs(1), typing.ExactArgs(1),
typing.WithTypes(object.ARRAY_OBJ), typing.WithTypes(object.ArrayType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -11,7 +11,7 @@ func Split(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"split", args, "split", args,
typing.RangeOfArgs(1, 2), typing.RangeOfArgs(1, 2),
typing.WithTypes(object.STRING_OBJ, object.STRING_OBJ), typing.WithTypes(object.StringType, object.StringType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -14,5 +14,5 @@ func TypeOf(args ...object.Object) object.Object {
return newError(err.Error()) return newError(err.Error())
} }
return &object.String{Value: string(args[0].Type())} return &object.String{Value: args[0].Type().String()}
} }

View File

@@ -11,7 +11,7 @@ func Upper(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"upper", args, "upper", args,
typing.ExactArgs(1), typing.ExactArgs(1),
typing.WithTypes(object.STRING_OBJ), typing.WithTypes(object.StringType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -11,7 +11,7 @@ func Write(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"write", args, "write", args,
typing.ExactArgs(2), typing.ExactArgs(2),
typing.WithTypes(object.INTEGER_OBJ, object.INTEGER_OBJ), typing.WithTypes(object.IntegerType, object.IntegerType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -11,7 +11,7 @@ func WriteFile(args ...object.Object) object.Object {
if err := typing.Check( if err := typing.Check(
"writefile", args, "writefile", args,
typing.ExactArgs(2), typing.ExactArgs(2),
typing.WithTypes(object.STRING_OBJ, object.STRING_OBJ), typing.WithTypes(object.StringType, object.StringType),
); err != nil { ); err != nil {
return newError(err.Error()) return newError(err.Error())
} }

View File

@@ -67,8 +67,7 @@ func (e *encoder) WriteValue(data any) error {
func (e *encoder) WriteObjects(objs ...object.Object) (err error) { func (e *encoder) WriteObjects(objs ...object.Object) (err error) {
for _, obj := range objs { for _, obj := range objs {
err = errors.Join(err, e.WriteValue(len(string(obj.Type())))) err = errors.Join(err, e.WriteValue(obj.Type()))
err = errors.Join(err, e.WriteString(string(obj.Type())))
switch o := obj.(type) { switch o := obj.(type) {
case *object.Null: case *object.Null:
@@ -145,16 +144,16 @@ func (d *decoder) String(len int) (s string) {
func (d *decoder) Objects(len int) (o []object.Object) { func (d *decoder) Objects(len int) (o []object.Object) {
for i := 0; i < len; i++ { for i := 0; i < len; i++ {
switch t := d.String(d.Int()); t { switch t := object.Type(d.Int()); t {
case object.NULL_OBJ: case object.NullType:
o = append(o, &object.Null{}) o = append(o, &object.Null{})
case object.BOOLEAN_OBJ: case object.BooleanType:
o = append(o, &object.Boolean{Value: d.Byte() == 1}) o = append(o, &object.Boolean{Value: d.Byte() == 1})
case object.INTEGER_OBJ: case object.IntegerType:
o = append(o, &object.Integer{Value: d.Int64()}) o = append(o, &object.Integer{Value: d.Int64()})
case object.STRING_OBJ: case object.StringType:
o = append(o, &object.String{Value: d.String(d.Int())}) o = append(o, &object.String{Value: d.String(d.Int())})
case object.COMPILED_FUNCTION_OBJ: case object.CFunctionType:
// The order of the fields has to reflect the data layout in the encoded bytecode. // The order of the fields has to reflect the data layout in the encoded bytecode.
o = append(o, &object.CompiledFunction{ o = append(o, &object.CompiledFunction{
NumParameters: d.Int(), NumParameters: d.Int(),
@@ -162,7 +161,7 @@ func (d *decoder) Objects(len int) (o []object.Object) {
Instructions: d.Bytes(d.Int()), Instructions: d.Bytes(d.Int()),
}) })
default: default:
panic(fmt.Sprintf("decoder: unsupported decoding for type %s", t)) panic(fmt.Sprintf("decoder: unsupported decoding for type %d", t))
} }
} }
return return

View File

@@ -20,7 +20,7 @@ var (
func isError(obj object.Object) bool { func isError(obj object.Object) bool {
if obj != nil { if obj != nil {
return obj.Type() == object.ERROR_OBJ return obj.Type() == object.ErrorType
} }
return false return false
} }
@@ -262,7 +262,7 @@ func evalBlockStatements(block *ast.BlockStatement, env *object.Environment) obj
if result != nil { if result != nil {
rt := result.Type() rt := result.Type()
if rt == object.RETURN_VALUE_OBJ || rt == object.ERROR_OBJ { if rt == object.ReturnType || rt == object.ErrorType {
return result return result
} }
} }
@@ -281,7 +281,7 @@ func nativeBoolToBooleanObject(input bool) object.Object {
func evalPrefixExpression(operator string, right object.Object) object.Object { func evalPrefixExpression(operator string, right object.Object) object.Object {
switch operator { switch operator {
case "!": case "!":
if right.Type() == object.BOOLEAN_OBJ { if right.Type() == object.BooleanType {
return evalBooleanPrefixOperatorExpression(operator, right) return evalBooleanPrefixOperatorExpression(operator, right)
} }
return evalIntegerPrefixOperatorExpression(operator, right) return evalIntegerPrefixOperatorExpression(operator, right)
@@ -293,7 +293,7 @@ func evalPrefixExpression(operator string, right object.Object) object.Object {
} }
func evalBooleanPrefixOperatorExpression(operator string, right object.Object) object.Object { func evalBooleanPrefixOperatorExpression(operator string, right object.Object) object.Object {
if right.Type() != object.BOOLEAN_OBJ { if right.Type() != object.BooleanType {
return newError("unknown operator: %s%s", operator, right.Type()) return newError("unknown operator: %s%s", operator, right.Type())
} }
@@ -310,7 +310,7 @@ func evalBooleanPrefixOperatorExpression(operator string, right object.Object) o
} }
func evalIntegerPrefixOperatorExpression(operator string, right object.Object) object.Object { func evalIntegerPrefixOperatorExpression(operator string, right object.Object) object.Object {
if right.Type() != object.INTEGER_OBJ { if right.Type() != object.IntegerType {
return newError("unknown operator: -%s", right.Type()) return newError("unknown operator: -%s", right.Type())
} }
@@ -331,7 +331,7 @@ func evalInfixExpression(operator string, left, right object.Object) object.Obje
switch { switch {
// {"a": 1} + {"b": 2} // {"a": 1} + {"b": 2}
case operator == "+" && left.Type() == object.HASH_OBJ && right.Type() == object.HASH_OBJ: case operator == "+" && left.Type() == object.HashType && right.Type() == object.HashType:
leftVal := left.(*object.Hash).Pairs leftVal := left.(*object.Hash).Pairs
rightVal := right.(*object.Hash).Pairs rightVal := right.(*object.Hash).Pairs
pairs := make(map[object.HashKey]object.HashPair) pairs := make(map[object.HashKey]object.HashPair)
@@ -344,7 +344,7 @@ func evalInfixExpression(operator string, left, right object.Object) object.Obje
return &object.Hash{Pairs: pairs} return &object.Hash{Pairs: pairs}
// [1] + [2] // [1] + [2]
case operator == "+" && left.Type() == object.ARRAY_OBJ && right.Type() == object.ARRAY_OBJ: case operator == "+" && left.Type() == object.ArrayType && right.Type() == object.ArrayType:
leftVal := left.(*object.Array).Elements leftVal := left.(*object.Array).Elements
rightVal := right.(*object.Array).Elements rightVal := right.(*object.Array).Elements
elements := make([]object.Object, len(leftVal)+len(rightVal)) elements := make([]object.Object, len(leftVal)+len(rightVal))
@@ -352,7 +352,7 @@ func evalInfixExpression(operator string, left, right object.Object) object.Obje
return &object.Array{Elements: elements} return &object.Array{Elements: elements}
// [1] * 3 // [1] * 3
case operator == "*" && left.Type() == object.ARRAY_OBJ && right.Type() == object.INTEGER_OBJ: case operator == "*" && left.Type() == object.ArrayType && right.Type() == object.IntegerType:
leftVal := left.(*object.Array).Elements leftVal := left.(*object.Array).Elements
rightVal := int(right.(*object.Integer).Value) rightVal := int(right.(*object.Integer).Value)
elements := leftVal elements := leftVal
@@ -362,7 +362,7 @@ func evalInfixExpression(operator string, left, right object.Object) object.Obje
return &object.Array{Elements: elements} return &object.Array{Elements: elements}
// 3 * [1] // 3 * [1]
case operator == "*" && left.Type() == object.INTEGER_OBJ && right.Type() == object.ARRAY_OBJ: case operator == "*" && left.Type() == object.IntegerType && right.Type() == object.ArrayType:
leftVal := int(left.(*object.Integer).Value) leftVal := int(left.(*object.Integer).Value)
rightVal := right.(*object.Array).Elements rightVal := right.(*object.Array).Elements
elements := rightVal elements := rightVal
@@ -372,13 +372,13 @@ func evalInfixExpression(operator string, left, right object.Object) object.Obje
return &object.Array{Elements: elements} return &object.Array{Elements: elements}
// " " * 4 // " " * 4
case operator == "*" && left.Type() == object.STRING_OBJ && right.Type() == object.INTEGER_OBJ: case operator == "*" && left.Type() == object.StringType && right.Type() == object.IntegerType:
leftVal := left.(*object.String).Value leftVal := left.(*object.String).Value
rightVal := right.(*object.Integer).Value rightVal := right.(*object.Integer).Value
return &object.String{Value: strings.Repeat(leftVal, int(rightVal))} return &object.String{Value: strings.Repeat(leftVal, int(rightVal))}
// 4 * " " // 4 * " "
case operator == "*" && left.Type() == object.INTEGER_OBJ && right.Type() == object.STRING_OBJ: case operator == "*" && left.Type() == object.IntegerType && right.Type() == object.StringType:
leftVal := left.(*object.Integer).Value leftVal := left.(*object.Integer).Value
rightVal := right.(*object.String).Value rightVal := right.(*object.String).Value
return &object.String{Value: strings.Repeat(rightVal, int(leftVal))} return &object.String{Value: strings.Repeat(rightVal, int(leftVal))}
@@ -396,11 +396,11 @@ func evalInfixExpression(operator string, left, right object.Object) object.Obje
case operator == ">": case operator == ">":
return nativeBoolToBooleanObject(left.(object.Comparable).Compare(right) == 1) return nativeBoolToBooleanObject(left.(object.Comparable).Compare(right) == 1)
case left.Type() == object.BOOLEAN_OBJ && right.Type() == object.BOOLEAN_OBJ: case left.Type() == object.BooleanType && right.Type() == object.BooleanType:
return evalBooleanInfixExpression(operator, left, right) return evalBooleanInfixExpression(operator, left, right)
case left.Type() == object.INTEGER_OBJ && right.Type() == object.INTEGER_OBJ: case left.Type() == object.IntegerType && right.Type() == object.IntegerType:
return evalIntegerInfixExpression(operator, left, right) return evalIntegerInfixExpression(operator, left, right)
case left.Type() == object.STRING_OBJ && right.Type() == object.STRING_OBJ: case left.Type() == object.StringType && right.Type() == object.StringType:
return evalStringInfixExpression(operator, left, right) return evalStringInfixExpression(operator, left, right)
default: default:
@@ -597,13 +597,13 @@ func unwrapReturnValue(obj object.Object) object.Object {
func evalIndexExpression(left, index object.Object) object.Object { func evalIndexExpression(left, index object.Object) object.Object {
switch { switch {
case left.Type() == object.STRING_OBJ && index.Type() == object.INTEGER_OBJ: case left.Type() == object.StringType && index.Type() == object.IntegerType:
return evalStringIndexExpression(left, index) return evalStringIndexExpression(left, index)
case left.Type() == object.ARRAY_OBJ && index.Type() == object.INTEGER_OBJ: case left.Type() == object.ArrayType && index.Type() == object.IntegerType:
return evalArrayIndexExpression(left, index) return evalArrayIndexExpression(left, index)
case left.Type() == object.HASH_OBJ: case left.Type() == object.HashType:
return evalHashIndexExpression(left, index) return evalHashIndexExpression(left, index)
case left.Type() == object.MODULE_OBJ: case left.Type() == object.ModuleType:
return EvalModuleIndexExpression(left, index) return EvalModuleIndexExpression(left, index)
default: default:
return newError("index operator not supported: %s", left.Type()) return newError("index operator not supported: %s", left.Type())

View File

@@ -10,8 +10,8 @@ type Array struct {
Elements []Object Elements []Object
} }
func (ao *Array) Type() ObjectType { func (ao *Array) Type() Type {
return ARRAY_OBJ return ArrayType
} }
func (ao *Array) Bool() bool { func (ao *Array) Bool() bool {

View File

@@ -12,8 +12,8 @@ func (b *Boolean) Bool() bool {
return b.Value return b.Value
} }
func (b *Boolean) Type() ObjectType { func (b *Boolean) Type() Type {
return BOOLEAN_OBJ return BooleanType
} }
func (b *Boolean) Inspect() string { func (b *Boolean) Inspect() string {

View File

@@ -11,8 +11,8 @@ func (b *Builtin) Bool() bool {
return true return true
} }
func (b *Builtin) Type() ObjectType { func (b *Builtin) Type() Type {
return BUILTIN_OBJ return BuiltinType
} }
func (b *Builtin) Inspect() string { func (b *Builtin) Inspect() string {

View File

@@ -15,8 +15,8 @@ func (cf *CompiledFunction) Bool() bool {
return true return true
} }
func (cf *CompiledFunction) Type() ObjectType { func (cf *CompiledFunction) Type() Type {
return COMPILED_FUNCTION_OBJ return CFunctionType
} }
func (cf *CompiledFunction) Inspect() string { func (cf *CompiledFunction) Inspect() string {
@@ -36,8 +36,8 @@ func (c *Closure) Bool() bool {
return true return true
} }
func (c *Closure) Type() ObjectType { func (c *Closure) Type() Type {
return CLOSURE_OBJ return ClosureType
} }
func (c *Closure) Inspect() string { func (c *Closure) Inspect() string {

View File

@@ -8,8 +8,8 @@ func (e *Error) Bool() bool {
return false return false
} }
func (e *Error) Type() ObjectType { func (e *Error) Type() Type {
return ERROR_OBJ return ErrorType
} }
func (e *Error) Inspect() string { func (e *Error) Inspect() string {

View File

@@ -16,8 +16,8 @@ func (f *Function) Bool() bool {
return false return false
} }
func (f *Function) Type() ObjectType { func (f *Function) Type() Type {
return FUNCTION_OBJ return FunctionType
} }
func (f *Function) Inspect() string { func (f *Function) Inspect() string {
@@ -50,8 +50,8 @@ func (rv *ReturnValue) Bool() bool {
return true return true
} }
func (rv *ReturnValue) Type() ObjectType { func (rv *ReturnValue) Type() Type {
return RETURN_VALUE_OBJ return ReturnType
} }
func (rv *ReturnValue) Inspect() string { func (rv *ReturnValue) Inspect() string {

View File

@@ -8,7 +8,7 @@ import (
) )
type HashKey struct { type HashKey struct {
Type ObjectType Type Type
Value uint64 Value uint64
} }
@@ -52,8 +52,8 @@ func (h *Hash) Bool() bool {
return len(h.Pairs) > 0 return len(h.Pairs) > 0
} }
func (h *Hash) Type() ObjectType { func (h *Hash) Type() Type {
return HASH_OBJ return HashType
} }
func (h *Hash) Inspect() string { func (h *Hash) Inspect() string {

View File

@@ -10,8 +10,8 @@ func (i *Integer) Bool() bool {
return i.Value != 0 return i.Value != 0
} }
func (i *Integer) Type() ObjectType { func (i *Integer) Type() Type {
return INTEGER_OBJ return IntegerType
} }
func (i *Integer) Inspect() string { func (i *Integer) Inspect() string {

View File

@@ -12,8 +12,8 @@ func (m Module) String() string {
return m.Inspect() return m.Inspect()
} }
func (m Module) Type() ObjectType { func (m Module) Type() Type {
return MODULE_OBJ return ModuleType
} }
func (m Module) Bool() bool { func (m Module) Bool() bool {

View File

@@ -6,8 +6,8 @@ func (n *Null) Bool() bool {
return false return false
} }
func (n *Null) Type() ObjectType { func (n *Null) Type() Type {
return NULL_OBJ return NullType
} }
func (n *Null) Inspect() string { func (n *Null) Inspect() string {

View File

@@ -3,24 +3,57 @@ package object
import "fmt" import "fmt"
// Type represents the type of an object // Type represents the type of an object
type ObjectType string type Type int
const ( const (
INTEGER_OBJ = "int" NullType = iota
BOOLEAN_OBJ = "bool" IntegerType
NULL_OBJ = "null" StringType
RETURN_VALUE_OBJ = "return" BooleanType
ERROR_OBJ = "error" ReturnType
FUNCTION_OBJ = "fn" ErrorType
STRING_OBJ = "str" FunctionType
BUILTIN_OBJ = "builtin" CFunctionType
ARRAY_OBJ = "array" BuiltinType
HASH_OBJ = "hash" ClosureType
COMPILED_FUNCTION_OBJ = "COMPILED_FUNCTION" ArrayType
CLOSURE_OBJ = "closure" HashType
MODULE_OBJ = "module" ModuleType
) )
func (t Type) String() string {
switch t {
case NullType:
return "null"
case IntegerType:
return "int"
case StringType:
return "str"
case BooleanType:
return "bool"
case ReturnType:
return "Return"
case ErrorType:
return "error"
case FunctionType:
return "fn"
case CFunctionType:
return "CFunction"
case BuiltinType:
return "Builtin"
case ClosureType:
return "Closure"
case ArrayType:
return "array"
case HashType:
return "hash"
case ModuleType:
return "module"
default:
return "???"
}
}
// Comparable is the interface for comparing two Object and their underlying // Comparable is the interface for comparing two Object and their underlying
// values. It is the responsibility of the caller (left) to check for types. // values. It is the responsibility of the caller (left) to check for types.
// Returns `true` iif the types and values are identical, `false` otherwise. // Returns `true` iif the types and values are identical, `false` otherwise.
@@ -45,7 +78,7 @@ type Immutable interface {
// `Type()` and `Inspect()` functions // `Type()` and `Inspect()` functions
type Object interface { type Object interface {
fmt.Stringer fmt.Stringer
Type() ObjectType Type() Type
Bool() bool Bool() bool
Inspect() string Inspect() string
} }

View File

@@ -17,8 +17,8 @@ func (s *String) Bool() bool {
return s.Value != "" return s.Value != ""
} }
func (s *String) Type() ObjectType { func (s *String) Type() Type {
return STRING_OBJ return StringType
} }
func (s *String) Inspect() string { func (s *String) Inspect() string {

View File

@@ -44,7 +44,7 @@ func RangeOfArgs(n, m int) CheckFunc {
} }
} }
func WithTypes(types ...object.ObjectType) CheckFunc { func WithTypes(types ...object.Type) CheckFunc {
return func(name string, args []object.Object) error { return func(name string, args []object.Object) error {
for i, t := range types { for i, t := range types {
if i < len(args) && args[i].Type() != t { if i < len(args) && args[i].Type() != t {

View File

@@ -495,9 +495,9 @@ func (vm *VM) Run() error {
func (vm *VM) executeSetItem(left, index, value object.Object) error { func (vm *VM) executeSetItem(left, index, value object.Object) error {
switch { switch {
case left.Type() == object.ARRAY_OBJ && index.Type() == object.INTEGER_OBJ: case left.Type() == object.ArrayType && index.Type() == object.IntegerType:
return vm.executeArraySetItem(left, index, value) return vm.executeArraySetItem(left, index, value)
case left.Type() == object.HASH_OBJ: case left.Type() == object.HashType:
return vm.executeHashSetItem(left, index, value) return vm.executeHashSetItem(left, index, value)
default: default:
return fmt.Errorf( return fmt.Errorf(
@@ -509,15 +509,15 @@ func (vm *VM) executeSetItem(left, index, value object.Object) error {
func (vm *VM) executeGetItem(left, index object.Object) error { func (vm *VM) executeGetItem(left, index object.Object) error {
switch { switch {
case left.Type() == object.STRING_OBJ && index.Type() == object.INTEGER_OBJ: case left.Type() == object.StringType && index.Type() == object.IntegerType:
return vm.executeStringGetItem(left, index) return vm.executeStringGetItem(left, index)
case left.Type() == object.STRING_OBJ && index.Type() == object.STRING_OBJ: case left.Type() == object.StringType && index.Type() == object.StringType:
return vm.executeStringIndex(left, index) return vm.executeStringIndex(left, index)
case left.Type() == object.ARRAY_OBJ && index.Type() == object.INTEGER_OBJ: case left.Type() == object.ArrayType && index.Type() == object.IntegerType:
return vm.executeArrayGetItem(left, index) return vm.executeArrayGetItem(left, index)
case left.Type() == object.HASH_OBJ: case left.Type() == object.HashType:
return vm.executeHashGetItem(left, index) return vm.executeHashGetItem(left, index)
case left.Type() == object.MODULE_OBJ: case left.Type() == object.ModuleType:
return vm.executeHashGetItem(left.(*object.Module).Attrs, index) return vm.executeHashGetItem(left.(*object.Module).Attrs, index)
default: default:
return fmt.Errorf( return fmt.Errorf(
@@ -653,7 +653,7 @@ func (vm *VM) executeBinaryOperation(op code.Opcode) error {
switch { switch {
// {"a": 1} + {"b": 2} // {"a": 1} + {"b": 2}
case op == code.OpAdd && left.Type() == object.HASH_OBJ && right.Type() == object.HASH_OBJ: case op == code.OpAdd && left.Type() == object.HashType && right.Type() == object.HashType:
leftVal := left.(*object.Hash).Pairs leftVal := left.(*object.Hash).Pairs
rightVal := right.(*object.Hash).Pairs rightVal := right.(*object.Hash).Pairs
pairs := make(map[object.HashKey]object.HashPair) pairs := make(map[object.HashKey]object.HashPair)
@@ -666,7 +666,7 @@ func (vm *VM) executeBinaryOperation(op code.Opcode) error {
return vm.push(&object.Hash{Pairs: pairs}) return vm.push(&object.Hash{Pairs: pairs})
// [1] + [2] // [1] + [2]
case op == code.OpAdd && left.Type() == object.ARRAY_OBJ && right.Type() == object.ARRAY_OBJ: case op == code.OpAdd && left.Type() == object.ArrayType && right.Type() == object.ArrayType:
leftVal := left.(*object.Array).Elements leftVal := left.(*object.Array).Elements
rightVal := right.(*object.Array).Elements rightVal := right.(*object.Array).Elements
elements := make([]object.Object, len(leftVal)+len(rightVal)) elements := make([]object.Object, len(leftVal)+len(rightVal))
@@ -674,7 +674,7 @@ func (vm *VM) executeBinaryOperation(op code.Opcode) error {
return vm.push(&object.Array{Elements: elements}) return vm.push(&object.Array{Elements: elements})
// [1] * 3 // [1] * 3
case op == code.OpMul && left.Type() == object.ARRAY_OBJ && right.Type() == object.INTEGER_OBJ: case op == code.OpMul && left.Type() == object.ArrayType && right.Type() == object.IntegerType:
leftVal := left.(*object.Array).Elements leftVal := left.(*object.Array).Elements
rightVal := int(right.(*object.Integer).Value) rightVal := int(right.(*object.Integer).Value)
elements := leftVal elements := leftVal
@@ -683,7 +683,7 @@ func (vm *VM) executeBinaryOperation(op code.Opcode) error {
} }
return vm.push(&object.Array{Elements: elements}) return vm.push(&object.Array{Elements: elements})
// 3 * [1] // 3 * [1]
case op == code.OpMul && left.Type() == object.INTEGER_OBJ && right.Type() == object.ARRAY_OBJ: case op == code.OpMul && left.Type() == object.IntegerType && right.Type() == object.ArrayType:
leftVal := int(left.(*object.Integer).Value) leftVal := int(left.(*object.Integer).Value)
rightVal := right.(*object.Array).Elements rightVal := right.(*object.Array).Elements
elements := rightVal elements := rightVal
@@ -693,21 +693,21 @@ func (vm *VM) executeBinaryOperation(op code.Opcode) error {
return vm.push(&object.Array{Elements: elements}) return vm.push(&object.Array{Elements: elements})
// " " * 4 // " " * 4
case op == code.OpMul && left.Type() == object.STRING_OBJ && right.Type() == object.INTEGER_OBJ: case op == code.OpMul && left.Type() == object.StringType && right.Type() == object.IntegerType:
leftVal := left.(*object.String).Value leftVal := left.(*object.String).Value
rightVal := right.(*object.Integer).Value rightVal := right.(*object.Integer).Value
return vm.push(&object.String{Value: strings.Repeat(leftVal, int(rightVal))}) return vm.push(&object.String{Value: strings.Repeat(leftVal, int(rightVal))})
// 4 * " " // 4 * " "
case op == code.OpMul && left.Type() == object.INTEGER_OBJ && right.Type() == object.STRING_OBJ: case op == code.OpMul && left.Type() == object.IntegerType && right.Type() == object.StringType:
leftVal := left.(*object.Integer).Value leftVal := left.(*object.Integer).Value
rightVal := right.(*object.String).Value rightVal := right.(*object.String).Value
return vm.push(&object.String{Value: strings.Repeat(rightVal, int(leftVal))}) return vm.push(&object.String{Value: strings.Repeat(rightVal, int(leftVal))})
case leftType == object.BOOLEAN_OBJ && rightType == object.BOOLEAN_OBJ: case leftType == object.BooleanType && rightType == object.BooleanType:
return vm.executeBinaryBooleanOperation(op, left, right) return vm.executeBinaryBooleanOperation(op, left, right)
case leftType == object.INTEGER_OBJ && rightType == object.INTEGER_OBJ: case leftType == object.IntegerType && rightType == object.IntegerType:
return vm.executeBinaryIntegerOperation(op, left, right) return vm.executeBinaryIntegerOperation(op, left, right)
case leftType == object.STRING_OBJ && rightType == object.STRING_OBJ: case leftType == object.StringType && rightType == object.StringType:
return vm.executeBinaryStringOperation(op, left, right) return vm.executeBinaryStringOperation(op, left, right)
default: default:
return fmt.Errorf("unsupported types for binary operation: %s %s", leftType, rightType) return fmt.Errorf("unsupported types for binary operation: %s %s", leftType, rightType)

View File

@@ -78,7 +78,7 @@ func VmREPL(args []string, debug bool) error {
continue continue
} }
if val := mvm.LastPoppedStackElem(); val.Type() != object.NULL_OBJ { if val := mvm.LastPoppedStackElem(); val.Type() != object.NullType {
fmt.Fprintln(t, val.Inspect()) fmt.Fprintln(t, val.Inspect())
} }
} }
@@ -176,7 +176,7 @@ func SimpleVmREPL(args []string, debug bool) {
continue continue
} }
if val := mvm.LastPoppedStackElem(); val.Type() != object.NULL_OBJ { if val := mvm.LastPoppedStackElem(); val.Type() != object.NullType {
fmt.Println(val.Inspect()) fmt.Println(val.Inspect())
} }
} }