Browse Source

Type checking for builtin commands.

Beoran 4 years ago
parent
commit
9e75ead458
5 changed files with 68 additions and 74 deletions
  1. 2 1
      ast.go
  2. 16 16
      builtin.go
  3. 12 11
      signature.go
  4. 22 22
      value.go
  5. 16 24
      vm.go

+ 2 - 1
ast.go

@@ -33,7 +33,8 @@ type AstMetaKindError AstBasicMetaKind
 type AstMetaKindFlatten AstBasicMetaKind
 
 
-/** The actual types are defined as constants, the meta types are used to be able to have different behavior for them.*/
+/* The actual types are defined as constants, the meta types are used to be 
+ * able to have different behavior for them. */
 const (
 	AstKindNone        = AstMetaKindNone("None")
 	AstKindProgram     = AstMetaKindProgram("Program")

+ 16 - 16
builtin.go

@@ -443,7 +443,7 @@ func (door * Door) Call(vm *VM, args...Value) []Value {
 	return Redispatch(door, vm, args...)
 }
 
-var doorSignature = NewSignature(WordTypeValue) 
+var doorSignature = NewSignature(WordType) 
 
 func (door * Door) Signature() Signature {
     return doorSignature
@@ -506,9 +506,9 @@ func openDoor(vm *VM, val ...Value) [] Value {
 }
 
 func (vm *VM) RegisterBuiltins() {
-	vm.RegisterBuiltinWithHelp("addi", addi, `adds two integers together`).Takes(IntTypeValue, IntTypeValue).Returns(BoolTypeValue)
-	vm.RegisterBuiltinWithHelp("addf", addf, `adds two floats together`).Takes(IntTypeValue, IntTypeValue).Returns(IntTypeValue)
-	vm.RegisterBuiltinWithHelp("andb", andb, `returns true if all it's arguments are true`).Takes(BoolTypeValue, BoolTypeValue).Returns(BoolTypeValue)
+	vm.RegisterBuiltinWithHelp("addi", addi, `adds two integers together`).Takes(IntType, IntType).Returns(BoolType)
+	vm.RegisterBuiltinWithHelp("addf", addf, `adds two floats together`).Takes(IntType, IntType).Returns(IntType)
+	vm.RegisterBuiltinWithHelp("andb", andb, `returns true if all it's arguments are true`).Takes(BoolType, BoolType).Returns(BoolType)
 	vm.RegisterBuiltin("cover", cover)
 	vm.RegisterBuiltin("fetchl", fetchl)
 	vm.RegisterBuiltin("fetchm", fetchm)
@@ -544,28 +544,28 @@ func (vm *VM) RegisterBuiltins() {
 	vm.AddOverloads("open", Over("openDoor", 0, DoorType))
 	
 	vm.AddOverloads("mul", 
-			Over("mulf", 0, FloatTypeValue, FloatTypeValue),
-			Over("muli", 0, IntTypeValue, IntTypeValue),
-			Over("mulf", 0, FloatTypeValue, IntTypeValue),
-			Over("mulf", 0, IntTypeValue, FloatTypeValue))
+			Over("mulf", 0, FloatType, FloatType),
+			Over("muli", 0, IntType, IntType),
+			Over("mulf", 0, FloatType, IntType),
+			Over("mulf", 0, IntType, FloatType))
 	
 	vm.AddOverloads("add", 
-			Over("addf", 0, FloatTypeValue, FloatTypeValue),
-			Over("addi", 0, IntTypeValue, IntTypeValue),
-			Over("addf", 0, FloatTypeValue, IntTypeValue),
-			Over("addf", 0, IntTypeValue, FloatTypeValue))
+			Over("addf", 0, FloatType, FloatType),
+			Over("addi", 0, IntType, IntType),
+			Over("addf", 0, FloatType, IntType),
+			Over("addf", 0, IntType, FloatType))
 	
 			
 	vm.SetHelp("mul", "	 Num: Multiplies two numbers. Cover for muli and mulf.")	
 	vm.AddOverloads("fetch", 
-			Over("fetchl", 0, ListTypeValue, IntTypeValue),
-			Over("fetchm", 0, MapTypeValue, AnyTypeValue),
+			Over("fetchl", 0, ListType, IntType),
+			Over("fetchm", 0, MapType, AnyType),
 		)			
 	vm.SetHelp("fetch", " storage, index. Fetch value in storage at given index.")
 	/*
 	vm.AddOverloads("store", 
-			Over("storel", ListTypeValue, IntTypeValue, AnyTypeValue),
-			Over("storem", MapTypeValue, AnyTypeValue, AnyTypeValue),
+			Over("storel", ListType, IntType, AnyType),
+			Over("storem", MapType, AnyType, AnyType),
 		)
 	vm.SetHelp("store", " storage, index, value. Store value in storage at given index.")
 	*/

+ 12 - 11
signature.go

@@ -43,7 +43,7 @@ func (s Signature) String() string {
 	sep := ""
 	for _, param := range s.Parameters {
         typ := param.Type
-		if typ != ZeroTypeValue { 
+		if typ != ZeroType { 
 			res = res + sep + typ.String()
 			sep = ", "
 		}
@@ -52,7 +52,7 @@ func (s Signature) String() string {
     sep = ""
     for _, param := range s.Returns {
         typ := param.Type
-		if typ != ZeroTypeValue { 
+		if typ != ZeroType { 
 			res = res + sep + typ.String()
 			sep = ", "
 		}
@@ -66,7 +66,7 @@ func (s Signature) StringWithNames() string {
 	sep := ""
 	for _, param := range s.Parameters {
         typ := param.Type
-		if typ != ZeroTypeValue { 
+		if typ != ZeroType { 
 			res = res + sep + string(param.Name) + " " + typ.String()
 			sep = ", "
 		}
@@ -75,7 +75,7 @@ func (s Signature) StringWithNames() string {
     sep = ""
     for _, param := range s.Returns {
         typ := param.Type
-		if typ != ZeroTypeValue { 
+		if typ != ZeroType { 
 			res = res + sep + string(param.Name) + " " + typ.String()
 			sep = ", "
 		}
@@ -106,8 +106,8 @@ func NewSignature(types ... TypeValue) Signature {
 
 func NewSignatureWithNames(param ...Value) (Signature, error) {
     sign := Signature{}
-	for i := 1 ; i < len(param) ; i += 2 {
-		name := param[i-1]
+	for i, j := 1, 0 ; i < len(param) ; i += 2 {
+        name := param[i-1]
 		typ  := param[i]
 		var ok bool
 		var nv WordValue
@@ -119,8 +119,9 @@ func NewSignatureWithNames(param ...Value) (Signature, error) {
 		if tv, ok = typ.(TypeValue); !ok {
 			return sign, fmt.Errorf("Not a type value: %v", typ)
 		}
-		sign.Parameters[i].Type = tv
-		sign.Parameters[i].Name = nv
+		sign.Parameters[j].Type = tv
+		sign.Parameters[j].Name = nv
+        j++
 	}
 	return sign, nil
 }
@@ -137,17 +138,17 @@ func CalculateSignature(arguments ...Value) Signature {
 		if i < len(arguments) {
 			signature.Parameters[i].Type = arguments[i].Type()
 		} else {			
-			signature.Parameters[i].Type = AnyTypeValue
+			signature.Parameters[i].Type = AnyType
 		}
 	}
 	return signature
 }
 
 func (tv TypeValue) IsMatch(other TypeValue) bool {
-	if tv == AnyTypeValue || other == AnyTypeValue {
+	if tv == AnyType || other == AnyType {
 		return true
 	}
-	if tv == ZeroTypeValue || other == ZeroTypeValue {
+	if tv == ZeroType || other == ZeroType {
 		return true
 	}
 	return tv == other

+ 22 - 22
value.go

@@ -40,18 +40,18 @@ type Values = []Value
 const (
 	TrueValue       = BoolValue(true)
 	FalseValue      = BoolValue(false)
-	IntTypeValue    = TypeValue("Int")
-	FloatTypeValue  = TypeValue("Float")
-	StringTypeValue = TypeValue("String")
-	BoolTypeValue   = TypeValue("Bool")
-	WordTypeValue   = TypeValue("Word")
-	ErrorTypeValue  = TypeValue("Error")
-	TypeTypeValue   = TypeValue("Type")
-	EmptyTypeValue  = TypeValue("Empty")
-	ListTypeValue   = TypeValue("List")
-	MapTypeValue    = TypeValue("Map")
-	AnyTypeValue    = TypeValue("Any")
-	ZeroTypeValue   = TypeValue("")
+	IntType    = TypeValue("Int")
+	FloatType  = TypeValue("Float")
+	StringType = TypeValue("String")
+	BoolType   = TypeValue("Bool")
+	WordType   = TypeValue("Word")
+	ErrorType  = TypeValue("Error")
+	TypeType   = TypeValue("Type")
+	EmptyType  = TypeValue("Empty")
+	ListType   = TypeValue("List")
+	MapType    = TypeValue("Map")
+	AnyType    = TypeValue("Any")
+	ZeroType   = TypeValue("")
 )
 
 var NilValue = Value(nil)
@@ -119,16 +119,16 @@ func (val MapValue) String() string {
 }
 
 
-func (v IntValue) Type() TypeValue    { return IntTypeValue }
-func (v FloatValue) Type() TypeValue  { return FloatTypeValue }
-func (v StringValue) Type() TypeValue { return StringTypeValue }
-func (v BoolValue) Type() TypeValue   { return BoolTypeValue }
-func (v WordValue) Type() TypeValue   { return WordTypeValue }
-func (v TypeValue) Type() TypeValue   { return TypeTypeValue }
-func (v ErrorValue) Type() TypeValue  { return ErrorTypeValue }
-func (v EmptyValue) Type() TypeValue  { return EmptyTypeValue }
-func (v ListValue) Type() TypeValue   { return ListTypeValue }
-func (v MapValue) Type() TypeValue    { return MapTypeValue }
+func (v IntValue) Type() TypeValue    { return IntType }
+func (v FloatValue) Type() TypeValue  { return FloatType }
+func (v StringValue) Type() TypeValue { return StringType }
+func (v BoolValue) Type() TypeValue   { return BoolType }
+func (v WordValue) Type() TypeValue   { return WordType }
+func (v TypeValue) Type() TypeValue   { return TypeType }
+func (v ErrorValue) Type() TypeValue  { return ErrorType }
+func (v EmptyValue) Type() TypeValue  { return EmptyType }
+func (v ListValue) Type() TypeValue   { return ListType }
+func (v MapValue) Type() TypeValue    { return MapType }
 
 func NewErrorValuef(format string, args ...interface{}) ErrorValue {
 	err := fmt.Errorf(format, args...)

+ 16 - 24
vm.go

@@ -180,7 +180,9 @@ func (defined *DefinedValue) Call(vm *VM, arguments ...Value) []Value {
 		}
 		param := defined.signature.Parameters[i]
 		expectedType := param.Type
-		if !expectedType.IsMatch(arg.Type()) {
+		vm.Trace("Signature check: %d %v", i, param)
+
+        if !expectedType.IsMatch(arg.Type()) {
 			return Fail(NewErrorValuef("Argument %d type mismatch: %s<->%s", i, expectedType, arg.Type()))
 		}
 		vm.Register(param.Name.String(), arg)
@@ -189,7 +191,6 @@ func (defined *DefinedValue) Call(vm *VM, arguments ...Value) []Value {
 	
 	res := defined.Body.Call(vm, arguments...)
 	return res
-
 }
 
 func (defined *DefinedValue) Help() string {
@@ -543,7 +544,7 @@ func (vm *VM) PopScope() *Scope {
 
 func (block * BlockValue) Call(vm *VM, arguments ...Value) []Value {
     ast := block.Ast
-    // Now, don't run the bloc itself but the Statements node
+    // Now, don't run the block itself but the Statements node
     // that should be in it.
     children := ast.Children()
     if len(children) < 1 {
@@ -558,31 +559,22 @@ func (block * BlockValue) Call(vm *VM, arguments ...Value) []Value {
 }
 
 func (builtin * BuiltinValue) Call(vm *VM, arguments ...Value) []Value {
-	handler := builtin.Handler
-	return handler.Call(vm, arguments...)
-}
-
-	
-/*
-func (vm *VM) CallDefined(ast *Ast, arguments ...Value) []Value {	
-	arr := vm.RunChildren(*ast, arguments...)
-	return arr
-}
-
-func (vm *VM) CallBlock(ast *Ast, arguments ...Value) []Value {
-	arr := vm.RunChildren(*ast, arguments...)
-	return arr
-}
+	for i , arg := range arguments {
+		if i >= len(builtin.signature.Parameters) {
+			break
+		}
+		param := builtin.signature.Parameters[i]
+		expectedType := param.Type
+		vm.Trace("Signature check: %d %v", i, param)
 
-func (vm *VM) CallBuiltin(handler Handler, arguments ...Value) []Value {
+        if !expectedType.IsMatch(arg.Type()) {
+			return Fail(NewErrorValuef("Argument %d type mismatch: %s<->%s", i, expectedType, arg.Type()))
+		}
+	}
+    handler := builtin.Handler
 	return handler.Call(vm, arguments...)
 }
 
-func (vm *VM) CallCover(cover * CoverValue, arguments ...Value) []Value {
-	return cover.Call(vm, arguments...)
-}
-*/
-
 
 func (vm *VM) AddTrace(err error) error {
 	res := ""