Refactor Type to be an int
This commit is contained in:
@@ -41,7 +41,7 @@ func (p *Program) String() string {
|
||||
var s strings.Builder
|
||||
|
||||
for _, stmt := range p.Statements {
|
||||
s.WriteString(fmt.Sprintf("%s\n", stmt.String()))
|
||||
s.WriteString(stmt.String())
|
||||
}
|
||||
|
||||
return s.String()
|
||||
|
||||
@@ -10,7 +10,7 @@ func Abs(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"abs", args,
|
||||
typing.ExactArgs(1),
|
||||
typing.WithTypes(object.INTEGER_OBJ),
|
||||
typing.WithTypes(object.IntegerType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ func Accept(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"accept", args,
|
||||
typing.ExactArgs(1),
|
||||
typing.WithTypes(object.INTEGER_OBJ),
|
||||
typing.WithTypes(object.IntegerType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ func Assert(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"assert", args,
|
||||
typing.ExactArgs(2),
|
||||
typing.WithTypes(object.BOOLEAN_OBJ, object.STRING_OBJ),
|
||||
typing.WithTypes(object.BooleanType, object.StringType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ func Bin(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"bin", args,
|
||||
typing.ExactArgs(1),
|
||||
typing.WithTypes(object.INTEGER_OBJ),
|
||||
typing.WithTypes(object.IntegerType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ func Bind(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"bind", args,
|
||||
typing.ExactArgs(2),
|
||||
typing.WithTypes(object.INTEGER_OBJ, object.INTEGER_OBJ),
|
||||
typing.WithTypes(object.IntegerType, object.IntegerType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ func Chr(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"chr", args,
|
||||
typing.ExactArgs(1),
|
||||
typing.WithTypes(object.INTEGER_OBJ),
|
||||
typing.WithTypes(object.IntegerType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ func Close(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"close", args,
|
||||
typing.ExactArgs(1),
|
||||
typing.WithTypes(object.INTEGER_OBJ),
|
||||
typing.WithTypes(object.IntegerType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ func Connect(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"connect", args,
|
||||
typing.ExactArgs(2),
|
||||
typing.WithTypes(object.INTEGER_OBJ, object.STRING_OBJ),
|
||||
typing.WithTypes(object.IntegerType, object.StringType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ func Divmod(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"divmod", args,
|
||||
typing.ExactArgs(2),
|
||||
typing.WithTypes(object.INTEGER_OBJ, object.INTEGER_OBJ),
|
||||
typing.WithTypes(object.IntegerType, object.IntegerType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ func Exit(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"exit", args,
|
||||
typing.RangeOfArgs(0, 1),
|
||||
typing.WithTypes(object.INTEGER_OBJ),
|
||||
typing.WithTypes(object.IntegerType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ func FFI(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"ffi", args,
|
||||
typing.ExactArgs(2),
|
||||
typing.WithTypes(object.STRING_OBJ, object.STRING_OBJ),
|
||||
typing.WithTypes(object.StringType, object.StringType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ func Find(args ...object.Object) object.Object {
|
||||
if haystack, ok := args[0].(*object.String); ok {
|
||||
if err := typing.Check(
|
||||
"find", args,
|
||||
typing.WithTypes(object.STRING_OBJ, object.STRING_OBJ),
|
||||
typing.WithTypes(object.StringType, object.StringType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
@@ -46,7 +46,7 @@ func Find(args ...object.Object) object.Object {
|
||||
}
|
||||
|
||||
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(),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ func First(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"first", args,
|
||||
typing.ExactArgs(1),
|
||||
typing.WithTypes(object.ARRAY_OBJ),
|
||||
typing.WithTypes(object.ArrayType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ func Hex(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"hex", args,
|
||||
typing.ExactArgs(1),
|
||||
typing.WithTypes(object.INTEGER_OBJ),
|
||||
typing.WithTypes(object.IntegerType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ func Input(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"input", args,
|
||||
typing.RangeOfArgs(0, 1),
|
||||
typing.WithTypes(object.STRING_OBJ),
|
||||
typing.WithTypes(object.StringType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ func Join(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"join", args,
|
||||
typing.ExactArgs(2),
|
||||
typing.WithTypes(object.ARRAY_OBJ, object.STRING_OBJ),
|
||||
typing.WithTypes(object.ArrayType, object.StringType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ func Last(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"last", args,
|
||||
typing.ExactArgs(1),
|
||||
typing.WithTypes(object.ARRAY_OBJ),
|
||||
typing.WithTypes(object.ArrayType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ func Listen(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"listen", args,
|
||||
typing.ExactArgs(2),
|
||||
typing.WithTypes(object.INTEGER_OBJ, object.INTEGER_OBJ),
|
||||
typing.WithTypes(object.IntegerType, object.IntegerType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ func Lower(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"lower", args,
|
||||
typing.ExactArgs(1),
|
||||
typing.WithTypes(object.STRING_OBJ),
|
||||
typing.WithTypes(object.StringType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ func Max(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"max", args,
|
||||
typing.ExactArgs(1),
|
||||
typing.WithTypes(object.ARRAY_OBJ),
|
||||
typing.WithTypes(object.ArrayType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
@@ -23,7 +23,7 @@ func Max(args ...object.Object) object.Object {
|
||||
if i, ok := e.(*object.Integer); ok {
|
||||
xs = append(xs, int(i.Value))
|
||||
} 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)
|
||||
|
||||
@@ -11,7 +11,7 @@ func Min(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"min", args,
|
||||
typing.ExactArgs(1),
|
||||
typing.WithTypes(object.ARRAY_OBJ),
|
||||
typing.WithTypes(object.ArrayType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
@@ -23,7 +23,7 @@ func Min(args ...object.Object) object.Object {
|
||||
if i, ok := e.(*object.Integer); ok {
|
||||
xs = append(xs, int(i.Value))
|
||||
} 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)
|
||||
|
||||
@@ -12,7 +12,7 @@ func Oct(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"oct", args,
|
||||
typing.ExactArgs(1),
|
||||
typing.WithTypes(object.INTEGER_OBJ),
|
||||
typing.WithTypes(object.IntegerType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ func Open(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"open", args,
|
||||
typing.RangeOfArgs(1, 2),
|
||||
typing.WithTypes(object.STRING_OBJ, object.STRING_OBJ),
|
||||
typing.WithTypes(object.StringType, object.StringType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ func Ord(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"ord", args,
|
||||
typing.ExactArgs(1),
|
||||
typing.WithTypes(object.STRING_OBJ),
|
||||
typing.WithTypes(object.StringType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ func Pop(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"pop", args,
|
||||
typing.ExactArgs(1),
|
||||
typing.WithTypes(object.ARRAY_OBJ),
|
||||
typing.WithTypes(object.ArrayType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ func Pow(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"pow", args,
|
||||
typing.ExactArgs(2),
|
||||
typing.WithTypes(object.INTEGER_OBJ, object.INTEGER_OBJ),
|
||||
typing.WithTypes(object.IntegerType, object.IntegerType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ func Print(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"print", args,
|
||||
typing.MinimumArgs(1),
|
||||
typing.WithTypes(object.STRING_OBJ),
|
||||
typing.WithTypes(object.StringType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ func Push(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"push", args,
|
||||
typing.ExactArgs(2),
|
||||
typing.WithTypes(object.ARRAY_OBJ),
|
||||
typing.WithTypes(object.ArrayType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ func Read(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"read", args,
|
||||
typing.RangeOfArgs(1, 2),
|
||||
typing.WithTypes(object.INTEGER_OBJ, object.INTEGER_OBJ),
|
||||
typing.WithTypes(object.IntegerType, object.IntegerType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ func ReadFile(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"readfile", args,
|
||||
typing.ExactArgs(1),
|
||||
typing.WithTypes(object.STRING_OBJ),
|
||||
typing.WithTypes(object.StringType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ func Rest(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"rest", args,
|
||||
typing.ExactArgs(1),
|
||||
typing.WithTypes(object.ARRAY_OBJ),
|
||||
typing.WithTypes(object.ArrayType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ func Reversed(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"reversed", args,
|
||||
typing.ExactArgs(1),
|
||||
typing.WithTypes(object.ARRAY_OBJ),
|
||||
typing.WithTypes(object.ArrayType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ func Seek(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"seek", args,
|
||||
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 {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ func Socket(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"socket", args,
|
||||
typing.ExactArgs(1),
|
||||
typing.WithTypes(object.STRING_OBJ),
|
||||
typing.WithTypes(object.StringType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ func Sorted(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"sort", args,
|
||||
typing.ExactArgs(1),
|
||||
typing.WithTypes(object.ARRAY_OBJ),
|
||||
typing.WithTypes(object.ArrayType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ func Split(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"split", args,
|
||||
typing.RangeOfArgs(1, 2),
|
||||
typing.WithTypes(object.STRING_OBJ, object.STRING_OBJ),
|
||||
typing.WithTypes(object.StringType, object.StringType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -14,5 +14,5 @@ func TypeOf(args ...object.Object) object.Object {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
return &object.String{Value: string(args[0].Type())}
|
||||
return &object.String{Value: args[0].Type().String()}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ func Upper(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"upper", args,
|
||||
typing.ExactArgs(1),
|
||||
typing.WithTypes(object.STRING_OBJ),
|
||||
typing.WithTypes(object.StringType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ func Write(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"write", args,
|
||||
typing.ExactArgs(2),
|
||||
typing.WithTypes(object.INTEGER_OBJ, object.INTEGER_OBJ),
|
||||
typing.WithTypes(object.IntegerType, object.IntegerType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ func WriteFile(args ...object.Object) object.Object {
|
||||
if err := typing.Check(
|
||||
"writefile", args,
|
||||
typing.ExactArgs(2),
|
||||
typing.WithTypes(object.STRING_OBJ, object.STRING_OBJ),
|
||||
typing.WithTypes(object.StringType, object.StringType),
|
||||
); err != nil {
|
||||
return newError(err.Error())
|
||||
}
|
||||
|
||||
@@ -67,8 +67,7 @@ func (e *encoder) WriteValue(data any) error {
|
||||
|
||||
func (e *encoder) WriteObjects(objs ...object.Object) (err error) {
|
||||
for _, obj := range objs {
|
||||
err = errors.Join(err, e.WriteValue(len(string(obj.Type()))))
|
||||
err = errors.Join(err, e.WriteString(string(obj.Type())))
|
||||
err = errors.Join(err, e.WriteValue(obj.Type()))
|
||||
|
||||
switch o := obj.(type) {
|
||||
case *object.Null:
|
||||
@@ -145,16 +144,16 @@ func (d *decoder) String(len int) (s string) {
|
||||
|
||||
func (d *decoder) Objects(len int) (o []object.Object) {
|
||||
for i := 0; i < len; i++ {
|
||||
switch t := d.String(d.Int()); t {
|
||||
case object.NULL_OBJ:
|
||||
switch t := object.Type(d.Int()); t {
|
||||
case object.NullType:
|
||||
o = append(o, &object.Null{})
|
||||
case object.BOOLEAN_OBJ:
|
||||
case object.BooleanType:
|
||||
o = append(o, &object.Boolean{Value: d.Byte() == 1})
|
||||
case object.INTEGER_OBJ:
|
||||
case object.IntegerType:
|
||||
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())})
|
||||
case object.COMPILED_FUNCTION_OBJ:
|
||||
case object.CFunctionType:
|
||||
// The order of the fields has to reflect the data layout in the encoded bytecode.
|
||||
o = append(o, &object.CompiledFunction{
|
||||
NumParameters: d.Int(),
|
||||
@@ -162,7 +161,7 @@ func (d *decoder) Objects(len int) (o []object.Object) {
|
||||
Instructions: d.Bytes(d.Int()),
|
||||
})
|
||||
default:
|
||||
panic(fmt.Sprintf("decoder: unsupported decoding for type %s", t))
|
||||
panic(fmt.Sprintf("decoder: unsupported decoding for type %d", t))
|
||||
}
|
||||
}
|
||||
return
|
||||
|
||||
@@ -20,7 +20,7 @@ var (
|
||||
|
||||
func isError(obj object.Object) bool {
|
||||
if obj != nil {
|
||||
return obj.Type() == object.ERROR_OBJ
|
||||
return obj.Type() == object.ErrorType
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -262,7 +262,7 @@ func evalBlockStatements(block *ast.BlockStatement, env *object.Environment) obj
|
||||
|
||||
if result != nil {
|
||||
rt := result.Type()
|
||||
if rt == object.RETURN_VALUE_OBJ || rt == object.ERROR_OBJ {
|
||||
if rt == object.ReturnType || rt == object.ErrorType {
|
||||
return result
|
||||
}
|
||||
}
|
||||
@@ -281,7 +281,7 @@ func nativeBoolToBooleanObject(input bool) object.Object {
|
||||
func evalPrefixExpression(operator string, right object.Object) object.Object {
|
||||
switch operator {
|
||||
case "!":
|
||||
if right.Type() == object.BOOLEAN_OBJ {
|
||||
if right.Type() == object.BooleanType {
|
||||
return evalBooleanPrefixOperatorExpression(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 {
|
||||
if right.Type() != object.BOOLEAN_OBJ {
|
||||
if right.Type() != object.BooleanType {
|
||||
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 {
|
||||
if right.Type() != object.INTEGER_OBJ {
|
||||
if right.Type() != object.IntegerType {
|
||||
return newError("unknown operator: -%s", right.Type())
|
||||
}
|
||||
|
||||
@@ -331,7 +331,7 @@ func evalInfixExpression(operator string, left, right object.Object) object.Obje
|
||||
switch {
|
||||
|
||||
// {"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
|
||||
rightVal := right.(*object.Hash).Pairs
|
||||
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}
|
||||
|
||||
// [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
|
||||
rightVal := right.(*object.Array).Elements
|
||||
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}
|
||||
|
||||
// [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
|
||||
rightVal := int(right.(*object.Integer).Value)
|
||||
elements := leftVal
|
||||
@@ -362,7 +362,7 @@ func evalInfixExpression(operator string, left, right object.Object) object.Obje
|
||||
return &object.Array{Elements: elements}
|
||||
|
||||
// 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)
|
||||
rightVal := right.(*object.Array).Elements
|
||||
elements := rightVal
|
||||
@@ -372,13 +372,13 @@ func evalInfixExpression(operator string, left, right object.Object) object.Obje
|
||||
return &object.Array{Elements: elements}
|
||||
|
||||
// " " * 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
|
||||
rightVal := right.(*object.Integer).Value
|
||||
return &object.String{Value: strings.Repeat(leftVal, int(rightVal))}
|
||||
|
||||
// 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
|
||||
rightVal := right.(*object.String).Value
|
||||
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 == ">":
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
|
||||
default:
|
||||
@@ -597,13 +597,13 @@ func unwrapReturnValue(obj object.Object) object.Object {
|
||||
|
||||
func evalIndexExpression(left, index object.Object) object.Object {
|
||||
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)
|
||||
case left.Type() == object.ARRAY_OBJ && index.Type() == object.INTEGER_OBJ:
|
||||
case left.Type() == object.ArrayType && index.Type() == object.IntegerType:
|
||||
return evalArrayIndexExpression(left, index)
|
||||
case left.Type() == object.HASH_OBJ:
|
||||
case left.Type() == object.HashType:
|
||||
return evalHashIndexExpression(left, index)
|
||||
case left.Type() == object.MODULE_OBJ:
|
||||
case left.Type() == object.ModuleType:
|
||||
return EvalModuleIndexExpression(left, index)
|
||||
default:
|
||||
return newError("index operator not supported: %s", left.Type())
|
||||
|
||||
@@ -10,8 +10,8 @@ type Array struct {
|
||||
Elements []Object
|
||||
}
|
||||
|
||||
func (ao *Array) Type() ObjectType {
|
||||
return ARRAY_OBJ
|
||||
func (ao *Array) Type() Type {
|
||||
return ArrayType
|
||||
}
|
||||
|
||||
func (ao *Array) Bool() bool {
|
||||
|
||||
@@ -12,8 +12,8 @@ func (b *Boolean) Bool() bool {
|
||||
return b.Value
|
||||
}
|
||||
|
||||
func (b *Boolean) Type() ObjectType {
|
||||
return BOOLEAN_OBJ
|
||||
func (b *Boolean) Type() Type {
|
||||
return BooleanType
|
||||
}
|
||||
|
||||
func (b *Boolean) Inspect() string {
|
||||
|
||||
@@ -11,8 +11,8 @@ func (b *Builtin) Bool() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (b *Builtin) Type() ObjectType {
|
||||
return BUILTIN_OBJ
|
||||
func (b *Builtin) Type() Type {
|
||||
return BuiltinType
|
||||
}
|
||||
|
||||
func (b *Builtin) Inspect() string {
|
||||
|
||||
@@ -15,8 +15,8 @@ func (cf *CompiledFunction) Bool() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (cf *CompiledFunction) Type() ObjectType {
|
||||
return COMPILED_FUNCTION_OBJ
|
||||
func (cf *CompiledFunction) Type() Type {
|
||||
return CFunctionType
|
||||
}
|
||||
|
||||
func (cf *CompiledFunction) Inspect() string {
|
||||
@@ -36,8 +36,8 @@ func (c *Closure) Bool() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *Closure) Type() ObjectType {
|
||||
return CLOSURE_OBJ
|
||||
func (c *Closure) Type() Type {
|
||||
return ClosureType
|
||||
}
|
||||
|
||||
func (c *Closure) Inspect() string {
|
||||
|
||||
@@ -8,8 +8,8 @@ func (e *Error) Bool() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (e *Error) Type() ObjectType {
|
||||
return ERROR_OBJ
|
||||
func (e *Error) Type() Type {
|
||||
return ErrorType
|
||||
}
|
||||
|
||||
func (e *Error) Inspect() string {
|
||||
|
||||
@@ -16,8 +16,8 @@ func (f *Function) Bool() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (f *Function) Type() ObjectType {
|
||||
return FUNCTION_OBJ
|
||||
func (f *Function) Type() Type {
|
||||
return FunctionType
|
||||
}
|
||||
|
||||
func (f *Function) Inspect() string {
|
||||
@@ -50,8 +50,8 @@ func (rv *ReturnValue) Bool() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (rv *ReturnValue) Type() ObjectType {
|
||||
return RETURN_VALUE_OBJ
|
||||
func (rv *ReturnValue) Type() Type {
|
||||
return ReturnType
|
||||
}
|
||||
|
||||
func (rv *ReturnValue) Inspect() string {
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
)
|
||||
|
||||
type HashKey struct {
|
||||
Type ObjectType
|
||||
Type Type
|
||||
Value uint64
|
||||
}
|
||||
|
||||
@@ -52,8 +52,8 @@ func (h *Hash) Bool() bool {
|
||||
return len(h.Pairs) > 0
|
||||
}
|
||||
|
||||
func (h *Hash) Type() ObjectType {
|
||||
return HASH_OBJ
|
||||
func (h *Hash) Type() Type {
|
||||
return HashType
|
||||
}
|
||||
|
||||
func (h *Hash) Inspect() string {
|
||||
|
||||
@@ -10,8 +10,8 @@ func (i *Integer) Bool() bool {
|
||||
return i.Value != 0
|
||||
}
|
||||
|
||||
func (i *Integer) Type() ObjectType {
|
||||
return INTEGER_OBJ
|
||||
func (i *Integer) Type() Type {
|
||||
return IntegerType
|
||||
}
|
||||
|
||||
func (i *Integer) Inspect() string {
|
||||
|
||||
@@ -12,8 +12,8 @@ func (m Module) String() string {
|
||||
return m.Inspect()
|
||||
}
|
||||
|
||||
func (m Module) Type() ObjectType {
|
||||
return MODULE_OBJ
|
||||
func (m Module) Type() Type {
|
||||
return ModuleType
|
||||
}
|
||||
|
||||
func (m Module) Bool() bool {
|
||||
|
||||
@@ -6,8 +6,8 @@ func (n *Null) Bool() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (n *Null) Type() ObjectType {
|
||||
return NULL_OBJ
|
||||
func (n *Null) Type() Type {
|
||||
return NullType
|
||||
}
|
||||
|
||||
func (n *Null) Inspect() string {
|
||||
|
||||
@@ -3,24 +3,57 @@ package object
|
||||
import "fmt"
|
||||
|
||||
// Type represents the type of an object
|
||||
type ObjectType string
|
||||
type Type int
|
||||
|
||||
const (
|
||||
INTEGER_OBJ = "int"
|
||||
BOOLEAN_OBJ = "bool"
|
||||
NULL_OBJ = "null"
|
||||
RETURN_VALUE_OBJ = "return"
|
||||
ERROR_OBJ = "error"
|
||||
FUNCTION_OBJ = "fn"
|
||||
STRING_OBJ = "str"
|
||||
BUILTIN_OBJ = "builtin"
|
||||
ARRAY_OBJ = "array"
|
||||
HASH_OBJ = "hash"
|
||||
COMPILED_FUNCTION_OBJ = "COMPILED_FUNCTION"
|
||||
CLOSURE_OBJ = "closure"
|
||||
MODULE_OBJ = "module"
|
||||
NullType = iota
|
||||
IntegerType
|
||||
StringType
|
||||
BooleanType
|
||||
ReturnType
|
||||
ErrorType
|
||||
FunctionType
|
||||
CFunctionType
|
||||
BuiltinType
|
||||
ClosureType
|
||||
ArrayType
|
||||
HashType
|
||||
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
|
||||
// values. It is the responsibility of the caller (left) to check for types.
|
||||
// Returns `true` iif the types and values are identical, `false` otherwise.
|
||||
@@ -45,7 +78,7 @@ type Immutable interface {
|
||||
// `Type()` and `Inspect()` functions
|
||||
type Object interface {
|
||||
fmt.Stringer
|
||||
Type() ObjectType
|
||||
Type() Type
|
||||
Bool() bool
|
||||
Inspect() string
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@ func (s *String) Bool() bool {
|
||||
return s.Value != ""
|
||||
}
|
||||
|
||||
func (s *String) Type() ObjectType {
|
||||
return STRING_OBJ
|
||||
func (s *String) Type() Type {
|
||||
return StringType
|
||||
}
|
||||
|
||||
func (s *String) Inspect() string {
|
||||
|
||||
@@ -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 {
|
||||
for i, t := range types {
|
||||
if i < len(args) && args[i].Type() != t {
|
||||
|
||||
@@ -495,9 +495,9 @@ func (vm *VM) Run() error {
|
||||
|
||||
func (vm *VM) executeSetItem(left, index, value object.Object) error {
|
||||
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)
|
||||
case left.Type() == object.HASH_OBJ:
|
||||
case left.Type() == object.HashType:
|
||||
return vm.executeHashSetItem(left, index, value)
|
||||
default:
|
||||
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 {
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
case left.Type() == object.HASH_OBJ:
|
||||
case left.Type() == object.HashType:
|
||||
return vm.executeHashGetItem(left, index)
|
||||
case left.Type() == object.MODULE_OBJ:
|
||||
case left.Type() == object.ModuleType:
|
||||
return vm.executeHashGetItem(left.(*object.Module).Attrs, index)
|
||||
default:
|
||||
return fmt.Errorf(
|
||||
@@ -653,7 +653,7 @@ func (vm *VM) executeBinaryOperation(op code.Opcode) error {
|
||||
switch {
|
||||
|
||||
// {"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
|
||||
rightVal := right.(*object.Hash).Pairs
|
||||
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})
|
||||
|
||||
// [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
|
||||
rightVal := right.(*object.Array).Elements
|
||||
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})
|
||||
|
||||
// [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
|
||||
rightVal := int(right.(*object.Integer).Value)
|
||||
elements := leftVal
|
||||
@@ -683,7 +683,7 @@ func (vm *VM) executeBinaryOperation(op code.Opcode) error {
|
||||
}
|
||||
return vm.push(&object.Array{Elements: elements})
|
||||
// 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)
|
||||
rightVal := right.(*object.Array).Elements
|
||||
elements := rightVal
|
||||
@@ -693,21 +693,21 @@ func (vm *VM) executeBinaryOperation(op code.Opcode) error {
|
||||
return vm.push(&object.Array{Elements: elements})
|
||||
|
||||
// " " * 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
|
||||
rightVal := right.(*object.Integer).Value
|
||||
return vm.push(&object.String{Value: strings.Repeat(leftVal, int(rightVal))})
|
||||
// 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
|
||||
rightVal := right.(*object.String).Value
|
||||
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)
|
||||
case leftType == object.INTEGER_OBJ && rightType == object.INTEGER_OBJ:
|
||||
case leftType == object.IntegerType && rightType == object.IntegerType:
|
||||
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)
|
||||
default:
|
||||
return fmt.Errorf("unsupported types for binary operation: %s %s", leftType, rightType)
|
||||
|
||||
4
repl.go
4
repl.go
@@ -78,7 +78,7 @@ func VmREPL(args []string, debug bool) error {
|
||||
continue
|
||||
}
|
||||
|
||||
if val := mvm.LastPoppedStackElem(); val.Type() != object.NULL_OBJ {
|
||||
if val := mvm.LastPoppedStackElem(); val.Type() != object.NullType {
|
||||
fmt.Fprintln(t, val.Inspect())
|
||||
}
|
||||
}
|
||||
@@ -176,7 +176,7 @@ func SimpleVmREPL(args []string, debug bool) {
|
||||
continue
|
||||
}
|
||||
|
||||
if val := mvm.LastPoppedStackElem(); val.Type() != object.NULL_OBJ {
|
||||
if val := mvm.LastPoppedStackElem(); val.Type() != object.NullType {
|
||||
fmt.Println(val.Inspect())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user