2
0
Эх сурвалжийг харах

check argument for dynamic array 'add' method

Vladislav Folts 10 жил өмнө
parent
commit
8bde839f87

BIN
bin/compiled.zip


+ 41 - 24
src/eberon/EberonTypes.ob

@@ -1,5 +1,5 @@
 MODULE EberonTypes;
 MODULE EberonTypes;
-IMPORT Code, Context, JsArray, LanguageContext, Procedure, Types;
+IMPORT Code, Context, Errors, JsArray, Language, LanguageContext, Procedure, Types;
 
 
 TYPE
 TYPE
     CallGenerator = PROCEDURE(cx: LanguageContext.PType; type: Types.DefinedProcedure): Procedure.PCallGenerator;
     CallGenerator = PROCEDURE(cx: LanguageContext.PType; type: Types.DefinedProcedure): Procedure.PCallGenerator;
@@ -23,20 +23,22 @@ TYPE
     PDynamicArray* = POINTER TO DynamicArray;
     PDynamicArray* = POINTER TO DynamicArray;
 
 
     DynamicArrayMethodField = RECORD(Types.Field)
     DynamicArrayMethodField = RECORD(Types.Field)
+        method: POINTER TO DynamicArrayMethod
     END;
     END;
+
     (*
     (*
     DynamicArrayAddCall = RECORD(Procedure.StdCall)
     DynamicArrayAddCall = RECORD(Procedure.StdCall)
     END;
     END;
     *)
     *)
     DynamicArrayAddCallGenerator = RECORD(Procedure.CallGenerator)
     DynamicArrayAddCallGenerator = RECORD(Procedure.CallGenerator)
-        arg: Code.PExpression
+        cx: LanguageContext.PType;
+        elementsType: Types.PType;
+        argCode: Procedure.PArgumentsCode
     END;
     END;
 
 
     DynamicArrayMethod = RECORD(Procedure.Std)
     DynamicArrayMethod = RECORD(Procedure.Std)
+        elementsType: Types.PType
     END;
     END;
-VAR
-    dynamicArrayAdd: POINTER TO DynamicArrayMethodField;
-    dynamicArrayAddMethod: POINTER TO DynamicArrayMethod;
 
 
 PROCEDURE arrayDimensionDescription*(VAR a: Types.Array): STRING;
 PROCEDURE arrayDimensionDescription*(VAR a: Types.Array): STRING;
 VAR
 VAR
@@ -59,8 +61,14 @@ PROCEDURE DynamicArray.description(): STRING;
 END DynamicArray.description;
 END DynamicArray.description;
 
 
 PROCEDURE DynamicArray.denote(id: STRING): Types.PField;
 PROCEDURE DynamicArray.denote(id: STRING): Types.PField;
+VAR
+    result: POINTER TO DynamicArrayMethodField;
 BEGIN
 BEGIN
-    RETURN dynamicArrayAdd
+    NEW(result);
+    NEW(result.method);
+    result.method.name := "add";
+    result.method.elementsType := SELF.elementsType;
+    RETURN result
 END DynamicArray.denote;
 END DynamicArray.denote;
 
 
 PROCEDURE MethodType.designatorCode(id: STRING): STRING;
 PROCEDURE MethodType.designatorCode(id: STRING): STRING;
@@ -106,14 +114,14 @@ PROCEDURE MethodVariable.idType(): STRING;
     RETURN "method"
     RETURN "method"
 END MethodVariable.idType;
 END MethodVariable.idType;
 
 
-PROCEDURE makeMethodVariable*(type: Types.PType): Types.PProcedureId;
+PROCEDURE makeMethod*(type: Types.PType): Types.PProcedureId;
 VAR
 VAR
     result: POINTER TO MethodVariable;
     result: POINTER TO MethodVariable;
 BEGIN
 BEGIN
     NEW(result);
     NEW(result);
     result.type := type;
     result.type := type;
     RETURN result
     RETURN result
-END makeMethodVariable;
+END makeMethod;
 
 
 PROCEDURE makeDynamicArray*(elementsType: Types.PType): PDynamicArray;
 PROCEDURE makeDynamicArray*(elementsType: Types.PType): PDynamicArray;
 VAR
 VAR
@@ -133,32 +141,42 @@ PROCEDURE DynamicArrayMethodField.exported(): BOOLEAN;
 END DynamicArrayMethodField.exported;
 END DynamicArrayMethodField.exported;
 
 
 PROCEDURE DynamicArrayMethodField.type(): Types.PType;
 PROCEDURE DynamicArrayMethodField.type(): Types.PType;
-    RETURN dynamicArrayAddMethod
+    RETURN SELF.method
 END DynamicArrayMethodField.type;
 END DynamicArrayMethodField.type;
 
 
 PROCEDURE DynamicArrayMethodField.asVar(): Types.PId;
 PROCEDURE DynamicArrayMethodField.asVar(): Types.PId;
-    RETURN makeMethodVariable(dynamicArrayAddMethod)
+    RETURN makeMethod(SELF.method)
 END DynamicArrayMethodField.asVar;
 END DynamicArrayMethodField.asVar;
-(*
-PROCEDURE DynamicArrayAddCall.make(args: JsArray.Type; cx: LanguageContext.Type): Code.PExpression;
-BEGIN
-    arg <- Procedure.checkSingleArgument(args, SELF, cx.types);
-    RETURN Code.makeSimpleExpression(
-            SELF.varId + ".push(" + arg.code() + ")",
-            NIL)
-END DynamicArrayAddCall.make;
-*)
+
 PROCEDURE DynamicArrayAddCallGenerator.handleArgument(e: Code.PExpression);
 PROCEDURE DynamicArrayAddCallGenerator.handleArgument(e: Code.PExpression);
 BEGIN
 BEGIN
-    SELF.arg := e;
+    IF SELF.argCode # NIL THEN
+        Errors.raise("method 'add' expects one argument, got many");
+    END;
+
+    SELF.argCode := Procedure.makeArgumentsCode(SELF.cx);
+    Procedure.checkArgument(
+        e, 
+        Types.makeProcedureArgument(SELF.elementsType, FALSE), 
+        0, 
+        SELF.argCode, 
+        SELF.cx.types);
 END DynamicArrayAddCallGenerator.handleArgument;
 END DynamicArrayAddCallGenerator.handleArgument;
 
 
 PROCEDURE DynamicArrayAddCallGenerator.end(): Code.PExpression;
 PROCEDURE DynamicArrayAddCallGenerator.end(): Code.PExpression;
+BEGIN
+    IF SELF.argCode = NIL THEN
+        Errors.raise("method 'add' expects one argument, got nothing");
+    END;
     RETURN Code.makeSimpleExpression(
     RETURN Code.makeSimpleExpression(
-            "(" + SELF.arg.code() + ")",
+            "(" + SELF.argCode.result() + ")",
             NIL)
             NIL)
 END DynamicArrayAddCallGenerator.end;
 END DynamicArrayAddCallGenerator.end;
 
 
+PROCEDURE DynamicArrayMethod.description(): STRING;
+    RETURN "dynamic array method '" + SELF.name + "'"
+END DynamicArrayMethod.description;
+
 PROCEDURE DynamicArrayMethod.designatorCode(id: STRING): STRING;
 PROCEDURE DynamicArrayMethod.designatorCode(id: STRING): STRING;
     RETURN "push"
     RETURN "push"
 END DynamicArrayMethod.designatorCode;
 END DynamicArrayMethod.designatorCode;
@@ -168,11 +186,10 @@ VAR
     result: POINTER TO DynamicArrayAddCallGenerator;
     result: POINTER TO DynamicArrayAddCallGenerator;
 BEGIN
 BEGIN
     NEW(result);
     NEW(result);
+    result.cx := cx;
+    result.elementsType := SELF.elementsType;
     RETURN result
     RETURN result
 END DynamicArrayMethod.callGenerator;
 END DynamicArrayMethod.callGenerator;
 
 
 BEGIN
 BEGIN
-    NEW(dynamicArrayAddMethod);
-    dynamicArrayAddMethod.name := "'add'";
-    NEW(dynamicArrayAdd);
 END EberonTypes.
 END EberonTypes.

+ 1 - 1
src/eberon/eberon_context.js

@@ -359,7 +359,7 @@ var RecordFieldAsMethod = Context.RecordField.extend({
         Context.RecordField.prototype.init.call(this, field, type);
         Context.RecordField.prototype.init.call(this, field, type);
     },
     },
     asVar: function(){ 
     asVar: function(){ 
-        return EberonTypes.makeMethodVariable(this.type()); 
+        return EberonTypes.makeMethod(this.type()); 
     }
     }
 });
 });
 var RecordType = Type.Record.extend({
 var RecordType = Type.Record.extend({

+ 4 - 4
src/ob/Procedure.ob

@@ -55,14 +55,14 @@ TYPE
         call: PCall
         call: PCall
     END;
     END;
 
 
-    ArgumentsCode = RECORD
+    ArgumentsCode* = RECORD
         PROCEDURE write(actual: Code.PExpression; 
         PROCEDURE write(actual: Code.PExpression; 
                         expected: Types.PProcedureArgument; 
                         expected: Types.PProcedureArgument; 
                         cast: Cast.PCastOp
                         cast: Cast.PCastOp
                         );
                         );
-        PROCEDURE result(): STRING
+        PROCEDURE result*(): STRING
     END;
     END;
-    PArgumentsCode = POINTER TO ArgumentsCode;
+    PArgumentsCode* = POINTER TO ArgumentsCode;
 
 
     GenArgCode = RECORD(ArgumentsCode)
     GenArgCode = RECORD(ArgumentsCode)
         code: STRING;
         code: STRING;
@@ -74,7 +74,7 @@ TYPE
 VAR
 VAR
     predefined*: JsArray.Type;
     predefined*: JsArray.Type;
 
 
-PROCEDURE checkArgument(
+PROCEDURE checkArgument*(
     actual: Code.PExpression; 
     actual: Code.PExpression; 
     expected: Types.PProcedureArgument; 
     expected: Types.PProcedureArgument; 
     pos: INTEGER;
     pos: INTEGER;

+ 1 - 1
src/ob/Types.ob

@@ -96,7 +96,7 @@ TYPE
     END;
     END;
 
 
     Array* = RECORD(NamedType)
     Array* = RECORD(NamedType)
-        elementsType: PType
+        elementsType-: PType
     END;
     END;
     PArray* = POINTER TO Array;
     PArray* = POINTER TO Array;
 
 

+ 12 - 0
test/expected/eberon/dynamic_array.js

@@ -55,7 +55,19 @@ var r = new T();
 function assignDynamicArrayFromStatic(){
 function assignDynamicArrayFromStatic(){
 	var static$ = RTL$.makeArray(3, 0);
 	var static$ = RTL$.makeArray(3, 0);
 	var dynamic = [];
 	var dynamic = [];
+	var dynamicString = [];
+	var dynamicByte = [];
+	var i = 0;
+	var s = '';
+	var byte = 0;
 	RTL$.copy(static$, dynamic);
 	RTL$.copy(static$, dynamic);
 	dynamic.push(3);
 	dynamic.push(3);
+	dynamic.push(i);
+	dynamic.push(byte);
+	dynamicString.push("abc");
+	dynamicString.push("\"");
+	dynamicString.push(s);
+	dynamicByte.push(byte);
+	dynamicByte.push(i & 0xFF);
 }
 }
 }();
 }();

+ 14 - 0
test/input/eberon/dynamic_array.ob

@@ -11,10 +11,24 @@ PROCEDURE assignDynamicArrayFromStatic();
 VAR 
 VAR 
     static: ARRAY 3 OF INTEGER;
     static: ARRAY 3 OF INTEGER;
     dynamic: ARRAY * OF INTEGER;
     dynamic: ARRAY * OF INTEGER;
+    dynamicString: ARRAY * OF STRING;
+    dynamicByte: ARRAY * OF BYTE;
+    i: INTEGER;
+    s: STRING;
+    byte: BYTE;
 BEGIN
 BEGIN
     dynamic := static;
     dynamic := static;
 
 
     dynamic.add(3);
     dynamic.add(3);
+    dynamic.add(i);
+    dynamic.add(byte);
+
+    dynamicString.add("abc");
+    dynamicString.add(22X);
+    dynamicString.add(s);
+    
+    dynamicByte.add(byte);
+    dynamicByte.add(i);
 END assignDynamicArrayFromStatic;
 END assignDynamicArrayFromStatic;
 
 
 END m.
 END m.

+ 7 - 3
test/test_unit_eberon.js

@@ -931,10 +931,14 @@ exports.suite = {
         ),
         ),
         "add": testWithContext(
         "add": testWithContext(
             context(grammar.statement, 
             context(grammar.statement, 
-                    "VAR a: ARRAY * OF INTEGER;"),
-            pass("a.add(123)"),
+                    "VAR a: ARRAY * OF INTEGER; byte: BYTE;"),
+            pass("a.add(123)",
+                 "a.add(byte)"),
             fail(["a.add := NIL", "cannot assign to method"],
             fail(["a.add := NIL", "cannot assign to method"],
-                 ["v <- a.add", "standard procedure 'add' cannot be referenced"]                
+                 ["v <- a.add", "dynamic array method 'add' cannot be referenced"],                
+                 ["a.add()", "method 'add' expects one argument, got nothing"],
+                 ["a.add(1, 2)", "method 'add' expects one argument, got many"],                
+                 ["a.add(TRUE)", "type mismatch for argument 1: 'BOOLEAN' cannot be converted to 'INTEGER'"]                
                 )
                 )
         )
         )
     }
     }