Fix VM memory allocation optimizations by reducing what we allocate on the heap
Some checks failed
Build / build (push) Successful in 10m25s
Publish Image / publish (push) Failing after 39s
Test / build (push) Successful in 11m19s

This commit is contained in:
Charles Smith
2024-03-31 20:44:50 -04:00
parent a85dc73954
commit aebbe43999
61 changed files with 383 additions and 370 deletions

View File

@@ -13,9 +13,9 @@ import (
)
var (
NULL = &object.Null{}
TRUE = &object.Boolean{Value: true}
FALSE = &object.Boolean{Value: false}
NULL = object.Null{}
TRUE = object.Boolean{Value: true}
FALSE = object.Boolean{Value: false}
)
func isError(obj object.Object) bool {
@@ -52,7 +52,7 @@ func Eval(node ast.Node, env *object.Environment) object.Object {
if isError(val) {
return val
}
return &object.ReturnValue{Value: val}
return object.ReturnValue{Value: val}
case *ast.BindExpression:
value := Eval(node.Value, env)
@@ -95,7 +95,7 @@ func Eval(node ast.Node, env *object.Environment) object.Object {
if isError(index) {
return index
}
if idx, ok := index.(*object.Integer); ok {
if idx, ok := index.(object.Integer); ok {
array.Elements[idx.Value] = value
} else {
return newError("cannot index array with %#v", index)
@@ -130,7 +130,7 @@ func Eval(node ast.Node, env *object.Environment) object.Object {
// Expressions
case *ast.IntegerLiteral:
return &object.Integer{Value: node.Value}
return object.Integer{Value: node.Value}
case *ast.Boolean:
return nativeBoolToBooleanObject(node.Value)
@@ -169,7 +169,7 @@ func Eval(node ast.Node, env *object.Environment) object.Object {
return applyFunction(function, args)
case *ast.StringLiteral:
return &object.String{Value: node.Value}
return object.String{Value: node.Value}
case *ast.ArrayLiteral:
elements := evalExpressions(node.Elements, env)
@@ -203,12 +203,12 @@ func evalImportExpression(ie *ast.ImportExpression, env *object.Environment) obj
return name
}
if s, ok := name.(*object.String); ok {
if s, ok := name.(object.String); ok {
attrs := EvalModule(s.Value)
if isError(attrs) {
return attrs
}
return &object.Module{Name: s.Value, Attrs: attrs}
return object.Module{Name: s.Value, Attrs: attrs}
}
return newError("ImportError: invalid import path '%s'", name)
}
@@ -243,9 +243,9 @@ func evalProgram(program *ast.Program, env *object.Environment) object.Object {
result = Eval(statement, env)
switch result := result.(type) {
case *object.ReturnValue:
case object.ReturnValue:
return result.Value
case *object.Error:
case object.Error:
return result
}
@@ -271,7 +271,7 @@ func evalBlockStatements(block *ast.BlockStatement, env *object.Environment) obj
return result
}
func nativeBoolToBooleanObject(input bool) object.Object {
func nativeBoolToBooleanObject(input bool) object.Boolean {
if input {
return TRUE
}
@@ -314,14 +314,14 @@ func evalIntegerPrefixOperatorExpression(operator string, right object.Object) o
return newError("unknown operator: -%s", right.Type())
}
value := right.(*object.Integer).Value
value := right.(object.Integer).Value
switch operator {
case "!":
return FALSE
case "~":
return &object.Integer{Value: ^value}
return object.Integer{Value: ^value}
case "-":
return &object.Integer{Value: -value}
return object.Integer{Value: -value}
default:
return newError("unknown operator: %s", operator)
}
@@ -354,7 +354,7 @@ func evalInfixExpression(operator string, left, right object.Object) object.Obje
// [1] * 3
case operator == "*" && left.Type() == object.ArrayType && right.Type() == object.IntegerType:
leftVal := left.(*object.Array).Elements
rightVal := int(right.(*object.Integer).Value)
rightVal := int(right.(object.Integer).Value)
elements := leftVal
for i := rightVal; i > 1; i-- {
elements = append(elements, leftVal...)
@@ -363,7 +363,7 @@ func evalInfixExpression(operator string, left, right object.Object) object.Obje
// 3 * [1]
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
elements := rightVal
for i := leftVal; i > 1; i-- {
@@ -373,15 +373,15 @@ func evalInfixExpression(operator string, left, right object.Object) object.Obje
// " " * 4
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))}
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.IntegerType && right.Type() == object.StringType:
leftVal := left.(*object.Integer).Value
rightVal := right.(*object.String).Value
return &object.String{Value: strings.Repeat(rightVal, int(leftVal))}
leftVal := left.(object.Integer).Value
rightVal := right.(object.String).Value
return object.String{Value: strings.Repeat(rightVal, int(leftVal))}
case operator == "==":
return nativeBoolToBooleanObject(left.(object.Comparable).Compare(right) == 0)
@@ -409,8 +409,8 @@ func evalInfixExpression(operator string, left, right object.Object) object.Obje
}
func evalBooleanInfixExpression(operator string, left, right object.Object) object.Object {
leftVal := left.(*object.Boolean).Value
rightVal := right.(*object.Boolean).Value
leftVal := left.(object.Boolean).Value
rightVal := right.(object.Boolean).Value
switch operator {
case "&&":
@@ -423,42 +423,42 @@ func evalBooleanInfixExpression(operator string, left, right object.Object) obje
}
func evalStringInfixExpression(operator string, left object.Object, right object.Object) object.Object {
leftVal := left.(*object.String).Value
rightVal := right.(*object.String).Value
leftVal := left.(object.String).Value
rightVal := right.(object.String).Value
switch operator {
case "+":
return &object.String{Value: leftVal + rightVal}
return object.String{Value: leftVal + rightVal}
default:
return newError("unknown operator: %s %s %s", left.Type(), operator, right.Type())
}
}
func evalIntegerInfixExpression(operator string, left, right object.Object) object.Object {
leftVal := left.(*object.Integer).Value
rightVal := right.(*object.Integer).Value
leftVal := left.(object.Integer).Value
rightVal := right.(object.Integer).Value
switch operator {
case "+":
return &object.Integer{Value: leftVal + rightVal}
return object.Integer{Value: leftVal + rightVal}
case "-":
return &object.Integer{Value: leftVal - rightVal}
return object.Integer{Value: leftVal - rightVal}
case "*":
return &object.Integer{Value: leftVal * rightVal}
return object.Integer{Value: leftVal * rightVal}
case "/":
return &object.Integer{Value: leftVal / rightVal}
return object.Integer{Value: leftVal / rightVal}
case "%":
return &object.Integer{Value: leftVal % rightVal}
return object.Integer{Value: leftVal % rightVal}
case "|":
return &object.Integer{Value: leftVal | rightVal}
return object.Integer{Value: leftVal | rightVal}
case "^":
return &object.Integer{Value: leftVal ^ rightVal}
return object.Integer{Value: leftVal ^ rightVal}
case "&":
return &object.Integer{Value: leftVal & rightVal}
return object.Integer{Value: leftVal & rightVal}
case "<<":
return &object.Integer{Value: leftVal << uint64(rightVal)}
return object.Integer{Value: leftVal << uint64(rightVal)}
case ">>":
return &object.Integer{Value: leftVal >> uint64(rightVal)}
return object.Integer{Value: leftVal >> uint64(rightVal)}
case "<":
return nativeBoolToBooleanObject(leftVal < rightVal)
case "<=":
@@ -504,11 +504,11 @@ func isTruthy(obj object.Object) bool {
}
}
func newError(format string, a ...interface{}) *object.Error {
return &object.Error{Message: fmt.Sprintf(format, a...)}
func newError(format string, a ...interface{}) object.Error {
return object.Error{Message: fmt.Sprintf(format, a...)}
}
// EvalModule evaluates the named module and returns a *object.Module objec
// EvalModule evaluates the named module and returns a object.Module objec
func EvalModule(name string) object.Object {
filename := utils.FindModule(name)
@@ -588,7 +588,7 @@ func extendFunctionEnv(fn *object.Function, args []object.Object) *object.Enviro
}
func unwrapReturnValue(obj object.Object) object.Object {
if returnValue, ok := obj.(*object.ReturnValue); ok {
if returnValue, ok := obj.(object.ReturnValue); ok {
return returnValue.Value
}
@@ -611,20 +611,20 @@ func evalIndexExpression(left, index object.Object) object.Object {
}
func EvalModuleIndexExpression(module, index object.Object) object.Object {
moduleObject := module.(*object.Module)
moduleObject := module.(object.Module)
return evalHashIndexExpression(moduleObject.Attrs, index)
}
func evalStringIndexExpression(str, index object.Object) object.Object {
stringObject := str.(*object.String)
idx := index.(*object.Integer).Value
stringObject := str.(object.String)
idx := index.(object.Integer).Value
max := int64((len(stringObject.Value)) - 1)
if idx < 0 || idx > max {
return &object.String{Value: ""}
return object.String{Value: ""}
}
return &object.String{Value: string(stringObject.Value[idx])}
return object.String{Value: string(stringObject.Value[idx])}
}
func evalHashIndexExpression(hash, index object.Object) object.Object {
@@ -645,7 +645,7 @@ func evalHashIndexExpression(hash, index object.Object) object.Object {
func evalArrayIndexExpression(array, index object.Object) object.Object {
arrayObject := array.(*object.Array)
idx := index.(*object.Integer).Value
idx := index.(object.Integer).Value
maxInx := int64(len(arrayObject.Elements) - 1)
if idx < 0 || idx > maxInx {