瀏覽代碼

get rid of JS.var in Code.ob

Vladislav Folts 11 年之前
父節點
當前提交
fb3cf7ea53
共有 5 個文件被更改,包括 108 次插入51 次删除
  1. 17 16
      src/context.js
  2. 38 7
      src/js/Code.js
  3. 42 17
      src/ob/Code.ob
  4. 4 4
      src/operator.js
  5. 7 7
      src/procedure.js

+ 17 - 16
src/context.js

@@ -129,7 +129,7 @@ exports.Integer = ChainedContext.extend({
     toInt: function(s){return parseInt(this.__result, 10);},
     toInt: function(s){return parseInt(this.__result, 10);},
     endParse: function(){
     endParse: function(){
         var n = this.toInt();
         var n = this.toInt();
-        this.parent().handleConst(basicTypes.integer, n, n.toString());
+        this.parent().handleConst(basicTypes.integer, Code.makeNumberConst(n), n.toString());
     }
     }
 });
 });
 
 
@@ -154,7 +154,7 @@ exports.Real = ChainedContext.extend({
     },
     },
     endParse: function(){
     endParse: function(){
         var n = Number(this.__result);
         var n = Number(this.__result);
-        this.parent().handleConst(basicTypes.real, n, n.toString());
+        this.parent().handleConst(basicTypes.real, Code.makeNumberConst(n), n.toString());
     }
     }
 });
 });
 
 
@@ -185,7 +185,7 @@ exports.String = ChainedContext.extend({
     toStr: function(s){return s;},
     toStr: function(s){return s;},
     endParse: function(){
     endParse: function(){
         var s = this.toStr(this.__result);
         var s = this.toStr(this.__result);
-        this.parent().handleConst(Type.makeString(s), s, escapeString(s));
+        this.parent().handleConst(Type.makeString(s), Code.makeStringConst(s), escapeString(s));
         }
         }
 });
 });
 
 
@@ -320,10 +320,10 @@ exports.Designator = ChainedContext.extend({
             throw new Errors.Error("ARRAY expected, got '" + type.description() + "'");
             throw new Errors.Error("ARRAY expected, got '" + type.description() + "'");
         var value = e.constValue();
         var value = e.constValue();
         var arrayLen = Type.arrayLength(type);
         var arrayLen = Type.arrayLength(type);
-        if (value !== undefined && arrayLen != Type.openArrayLength && value >= arrayLen)
+        if (value !== undefined && arrayLen != Type.openArrayLength && value.value >= arrayLen)
             throw new Errors.Error("index out of bounds: maximum possible index is "
             throw new Errors.Error("index out of bounds: maximum possible index is "
                                  + (Type.arrayLength(type) - 1)
                                  + (Type.arrayLength(type) - 1)
-                                 + ", got " + value );
+                                 + ", got " + value.value );
 
 
         this.__currentType = Type.arrayElementsType(type);
         this.__currentType = Type.arrayElementsType(type);
         this.__info = Type.makeVariable(this.__currentType, Type.isVariableReadOnly(this.__info));
         this.__info = Type.makeVariable(this.__currentType, Type.isVariableReadOnly(this.__info));
@@ -728,9 +728,9 @@ exports.ArrayDimensions = ChainedContext.extend({
         var value = e.constValue();
         var value = e.constValue();
         if (value === undefined)
         if (value === undefined)
             throw new Errors.Error("constant expression expected as ARRAY size");
             throw new Errors.Error("constant expression expected as ARRAY size");
-        if (value <= 0)
-            throw new Errors.Error("array size must be greater than 0, got " + value);
-        this.__dimensions.push(value);
+        if (value.value <= 0)
+            throw new Errors.Error("array size must be greater than 0, got " + value.value);
+        this.__dimensions.push(value.value);
     },
     },
     endParse: function(){
     endParse: function(){
         this.parent().handleDimensions(this.__dimensions);
         this.parent().handleDimensions(this.__dimensions);
@@ -970,9 +970,9 @@ exports.Factor = ChainedContext.extend({
         if (s == "NIL")
         if (s == "NIL")
             parent.handleConst(nilType, undefined, "null");
             parent.handleConst(nilType, undefined, "null");
         else if (s == "TRUE")
         else if (s == "TRUE")
-            parent.handleConst(basicTypes.bool, true, "true");
+            parent.handleConst(basicTypes.bool, Code.makeNumberConst(true), "true");
         else if (s == "FALSE")
         else if (s == "FALSE")
-            parent.handleConst(basicTypes.bool, false, "false");
+            parent.handleConst(basicTypes.bool, Code.makeNumberConst(false), "false");
         else if (s == "~")
         else if (s == "~")
             parent.handleLogicalNot();
             parent.handleLogicalNot();
     },
     },
@@ -989,10 +989,10 @@ exports.Set = ChainedContext.extend({
     handleElement: function(from, fromValue, to, toValue){
     handleElement: function(from, fromValue, to, toValue){
         if (fromValue !== undefined && (!to || toValue !== undefined)){
         if (fromValue !== undefined && (!to || toValue !== undefined)){
             if (to)
             if (to)
-                for(var i = fromValue; i <= toValue; ++i)
+                for(var i = fromValue.value; i <= toValue.value; ++i)
                     this.__value |= 1 << i;
                     this.__value |= 1 << i;
             else
             else
-                this.__value |= 1 << fromValue;
+                this.__value |= 1 << fromValue.value;
         }
         }
         else{
         else{
             if (this.__expr.length)
             if (this.__expr.length)
@@ -1006,7 +1006,7 @@ exports.Set = ChainedContext.extend({
     endParse: function(){
     endParse: function(){
         var parent = this.parent();
         var parent = this.parent();
         if (!this.__expr.length)
         if (!this.__expr.length)
-            parent.handleConst(basicTypes.set, this.__value, this.__value.toString());
+            parent.handleConst(basicTypes.set, Code.makeNumberConst(this.__value), this.__value.toString());
         else{
         else{
             var code = this.rtl().makeSet(this.__expr);
             var code = this.rtl().makeSet(this.__expr);
             if (this.__value)
             if (this.__value)
@@ -1272,8 +1272,8 @@ exports.CaseLabelList = ChainedContext.extend({
             this.parent().caseLabelBegin();
             this.parent().caseLabelBegin();
 
 
         var cond = to === undefined
         var cond = to === undefined
-            ? "$c === " + from
-            : "($c >= " + from + " && $c <= " + to + ")";
+            ? "$c === " + from.value
+            : "($c >= " + from.value + " && $c <= " + to.value + ")";
         this.codeGenerator().write(this.__glue + cond);
         this.codeGenerator().write(this.__glue + cond);
         this.__glue = " || ";
         this.__glue = " || ";
     },
     },
@@ -1317,6 +1317,7 @@ exports.CaseRange = ChainedContext.extend({
             if (!Type.stringAsChar(type, {set: function(v){value = v;}}))
             if (!Type.stringAsChar(type, {set: function(v){value = v;}}))
                 throw new Errors.Error("single-character string expected");
                 throw new Errors.Error("single-character string expected");
             type = basicTypes.ch;
             type = basicTypes.ch;
+            value = Code.makeNumberConst(value);
         }
         }
         this.handleLabel(type, value);
         this.handleLabel(type, value);
     },
     },
@@ -1416,7 +1417,7 @@ exports.For = ChainedContext.extend({
         else if ( value === undefined )
         else if ( value === undefined )
             throw new Errors.Error("constant expression expected as 'BY' parameter");
             throw new Errors.Error("constant expression expected as 'BY' parameter");
         else
         else
-            this.__by = value;
+            this.__by = value.value;
     },
     },
     codeGenerator: function(){
     codeGenerator: function(){
         if (this.__initExprParsed && !this.__toParsed)
         if (this.__initExprParsed && !this.__toParsed)

+ 38 - 7
src/js/Code.js

@@ -40,12 +40,28 @@ var Designator = RTL$.extend({
 		this.mScope = null;
 		this.mScope = null;
 	}
 	}
 });
 });
+var Const = RTL$.extend({
+	init: function Const(){
+	}
+});
+var NumberConst = Const.extend({
+	init: function NumberConst(){
+		Const.prototype.init.call(this);
+		this.value = 0;
+	}
+});
+var StringConst = Const.extend({
+	init: function StringConst(){
+		Const.prototype.init.call(this);
+		this.value = null;
+	}
+});
 var Expression = RTL$.extend({
 var Expression = RTL$.extend({
 	init: function Expression(){
 	init: function Expression(){
 		this.mCode = null;
 		this.mCode = null;
 		this.mType = null;
 		this.mType = null;
 		this.mDesignator = null;
 		this.mDesignator = null;
-		this.mConstValue = undefined;
+		this.mConstValue = null;
 		this.mMaxPrecedence = 0;
 		this.mMaxPrecedence = 0;
 	}
 	}
 });
 });
@@ -62,7 +78,6 @@ var Closure = Object.Type.extend({
 	}
 	}
 });
 });
 var nullGenerator = new NullGenerator();
 var nullGenerator = new NullGenerator();
-var undefined = undefined;
 NullGenerator.prototype.write = function(s/*Type*/){
 NullGenerator.prototype.write = function(s/*Type*/){
 }
 }
 NullGenerator.prototype.openScope = function(){
 NullGenerator.prototype.openScope = function(){
@@ -148,7 +163,21 @@ Expression.prototype.isTerm = function(){
 	return this.mDesignator == null && this.mMaxPrecedence == kNoPrecedence;
 	return this.mDesignator == null && this.mMaxPrecedence == kNoPrecedence;
 }
 }
 
 
-function makeExpressionWithPrecedence(code/*Type*/, type/*PType*/, designator/*PDesigantor*/, constValue/*JS.var*/, maxPrecedence/*INTEGER*/){
+function makeNumberConst(n/*REAL*/){
+	var result = null;
+	result = new NumberConst();
+	result.value = n;
+	return result;
+}
+
+function makeStringConst(s/*Type*/){
+	var result = null;
+	result = new StringConst();
+	result.value = s;
+	return result;
+}
+
+function makeExpressionWithPrecedence(code/*Type*/, type/*PType*/, designator/*PDesigantor*/, constValue/*PConst*/, maxPrecedence/*INTEGER*/){
 	var result = null;
 	var result = null;
 	result = new Expression();
 	result = new Expression();
 	result.mCode = code;
 	result.mCode = code;
@@ -159,12 +188,12 @@ function makeExpressionWithPrecedence(code/*Type*/, type/*PType*/, designator/*P
 	return result;
 	return result;
 }
 }
 
 
-function makeExpression(code/*Type*/, type/*PType*/, designator/*PDesigantor*/, constValue/*JS.var*/){
+function makeExpression(code/*Type*/, type/*PType*/, designator/*PDesigantor*/, constValue/*PConst*/){
 	return makeExpressionWithPrecedence(code, type, designator, constValue, kNoPrecedence);
 	return makeExpressionWithPrecedence(code, type, designator, constValue, kNoPrecedence);
 }
 }
 
 
 function makeSimpleExpression(code/*Type*/, type/*PType*/){
 function makeSimpleExpression(code/*Type*/, type/*PType*/){
-	return makeExpression(code, type, null, undefined);
+	return makeExpression(code, type, null, null);
 }
 }
 Designator.prototype.code = function(){
 Designator.prototype.code = function(){
 	return this.mCode;
 	return this.mCode;
@@ -203,7 +232,7 @@ function derefExpression(e/*PExpression*/){
 		result = e;
 		result = e;
 	}
 	}
 	else {
 	else {
-		result = makeExpression(JsString.concat(e.mCode, JsString.make(".get()")), e.mType, null, undefined);
+		result = makeSimpleExpression(JsString.concat(e.mCode, JsString.make(".get()")), e.mType);
 	}
 	}
 	return result;
 	return result;
 }
 }
@@ -214,7 +243,7 @@ function refExpression(e/*PExpression*/){
 		result = e;
 		result = e;
 	}
 	}
 	else {
 	else {
-		result = makeExpression(e.mDesignator.mRefCode(e.mDesignator.mCode), e.mType, null, undefined);
+		result = makeSimpleExpression(e.mDesignator.mRefCode(e.mDesignator.mCode), e.mType);
 	}
 	}
 	return result;
 	return result;
 }
 }
@@ -329,6 +358,8 @@ function makeModuleGenerator(name/*Type*/, imports/*Strings*/){
 }
 }
 exports.Expression = Expression;
 exports.Expression = Expression;
 exports.nullGenerator = function(){return nullGenerator;};
 exports.nullGenerator = function(){return nullGenerator;};
+exports.makeNumberConst = makeNumberConst;
+exports.makeStringConst = makeStringConst;
 exports.makeExpressionWithPrecedence = makeExpressionWithPrecedence;
 exports.makeExpressionWithPrecedence = makeExpressionWithPrecedence;
 exports.makeExpression = makeExpression;
 exports.makeExpression = makeExpression;
 exports.makeSimpleExpression = makeSimpleExpression;
 exports.makeSimpleExpression = makeSimpleExpression;

+ 42 - 17
src/ob/Code.ob

@@ -1,5 +1,5 @@
 MODULE Code;
 MODULE Code;
-IMPORT JS, JsMap, JsString, Context, Object, Stream, Symbols, Types;
+IMPORT JsMap, JsString, Context, Object, Stream, Symbols, Types;
 
 
 CONST
 CONST
     kTab = 09X;
     kTab = 09X;
@@ -46,24 +46,36 @@ TYPE
 
 
     PDesigantor = POINTER TO Designator;
     PDesigantor = POINTER TO Designator;
 
 
-    PExpression* = POINTER TO Expression;
+    Const = RECORD
+    END;
+    PConst = POINTER TO Const;
+
+    NumberConst = RECORD (Const)
+        value: REAL
+    END;
+
+    StringConst = RECORD (Const)
+        value: JsString.Type
+    END;
 
 
     Expression* = RECORD
     Expression* = RECORD
         PROCEDURE code(): JsString.Type;
         PROCEDURE code(): JsString.Type;
         PROCEDURE lval(): JsString.Type;
         PROCEDURE lval(): JsString.Type;
         PROCEDURE type(): Types.PType;
         PROCEDURE type(): Types.PType;
         PROCEDURE designator(): PDesigantor;
         PROCEDURE designator(): PDesigantor;
-        PROCEDURE constValue(): JS.var;
+        PROCEDURE constValue(): PConst;
         PROCEDURE maxPrecedence(): INTEGER;
         PROCEDURE maxPrecedence(): INTEGER;
         PROCEDURE isTerm(): BOOLEAN;
         PROCEDURE isTerm(): BOOLEAN;
 
 
         mCode: JsString.Type;
         mCode: JsString.Type;
         mType: Types.PType;
         mType: Types.PType;
         mDesignator: PDesigantor;
         mDesignator: PDesigantor;
-        mConstValue: JS.var;
+        mConstValue: PConst;
         mMaxPrecedence: INTEGER
         mMaxPrecedence: INTEGER
     END;
     END;
 
 
+    PExpression* = POINTER TO Expression;
+
     ModuleGenerator = RECORD
     ModuleGenerator = RECORD
         PROCEDURE prolog(): JsString.Type;
         PROCEDURE prolog(): JsString.Type;
         PROCEDURE epilog(exports: JsMap.Type): JsString.Type;
         PROCEDURE epilog(exports: JsMap.Type): JsString.Type;
@@ -80,7 +92,6 @@ TYPE
 
 
 VAR
 VAR
     nullGenerator*: NullGenerator;
     nullGenerator*: NullGenerator;
-    undefined: JS.var;
 
 
 PROCEDURE NullGenerator.write(s: JsString.Type);
 PROCEDURE NullGenerator.write(s: JsString.Type);
 END NullGenerator.write;
 END NullGenerator.write;
@@ -176,7 +187,7 @@ PROCEDURE Expression.designator(): PDesigantor;
     RETURN SELF.mDesignator
     RETURN SELF.mDesignator
 END Expression.designator;
 END Expression.designator;
 
 
-PROCEDURE Expression.constValue(): JS.var;
+PROCEDURE Expression.constValue(): PConst;
     RETURN SELF.mConstValue
     RETURN SELF.mConstValue
 END Expression.constValue;
 END Expression.constValue;
 
 
@@ -188,11 +199,29 @@ PROCEDURE Expression.isTerm(): BOOLEAN;
     RETURN (SELF.mDesignator = NIL) & (SELF.mMaxPrecedence = kNoPrecedence)
     RETURN (SELF.mDesignator = NIL) & (SELF.mMaxPrecedence = kNoPrecedence)
 END Expression.isTerm;
 END Expression.isTerm;
 
 
+PROCEDURE makeNumberConst*(n: REAL): PConst;
+VAR
+    result: POINTER TO NumberConst;
+BEGIN
+    NEW(result);
+    result.value := n;
+    RETURN result
+END makeNumberConst;
+
+PROCEDURE makeStringConst*(s: JsString.Type): PConst;
+VAR
+    result: POINTER TO StringConst;
+BEGIN
+    NEW(result);
+    result.value := s;
+    RETURN result
+END makeStringConst;
+
 PROCEDURE makeExpressionWithPrecedence*(
 PROCEDURE makeExpressionWithPrecedence*(
     code: JsString.Type; 
     code: JsString.Type; 
     type: Types.PType; 
     type: Types.PType; 
     designator: PDesigantor; 
     designator: PDesigantor; 
-    constValue: JS.var; 
+    constValue: PConst; 
     maxPrecedence: INTEGER): PExpression;
     maxPrecedence: INTEGER): PExpression;
 VAR
 VAR
     result: PExpression;
     result: PExpression;
@@ -210,7 +239,7 @@ PROCEDURE makeExpression*(
     code: JsString.Type; 
     code: JsString.Type; 
     type: Types.PType; 
     type: Types.PType; 
     designator: PDesigantor; 
     designator: PDesigantor; 
-    constValue: JS.var)
+    constValue: PConst)
     : PExpression;
     : PExpression;
     RETURN makeExpressionWithPrecedence(code, type, designator, constValue, kNoPrecedence)
     RETURN makeExpressionWithPrecedence(code, type, designator, constValue, kNoPrecedence)
 END makeExpression;
 END makeExpression;
@@ -219,7 +248,7 @@ PROCEDURE makeSimpleExpression*(
     code: JsString.Type; 
     code: JsString.Type; 
     type: Types.PType)
     type: Types.PType)
     : PExpression;
     : PExpression;
-    RETURN makeExpression(code, type, NIL, undefined)
+    RETURN makeExpression(code, type, NIL, NIL)
 END makeSimpleExpression;
 END makeSimpleExpression;
 
 
 PROCEDURE Designator.code(): JsString.Type;
 PROCEDURE Designator.code(): JsString.Type;
@@ -269,10 +298,8 @@ BEGIN
         OR ~(e.mDesignator.mInfo IS Types.PVariableRef) THEN
         OR ~(e.mDesignator.mInfo IS Types.PVariableRef) THEN
         result := e;
         result := e;
     ELSE
     ELSE
-        result := makeExpression(JsString.concat(e.mCode, JsString.make(".get()")),
-                                 e.mType,
-                                 NIL,
-                                 undefined);
+        result := makeSimpleExpression(JsString.concat(e.mCode, JsString.make(".get()")),
+                                       e.mType);
     END;
     END;
     RETURN result
     RETURN result
 END derefExpression;
 END derefExpression;
@@ -285,10 +312,8 @@ BEGIN
         OR (e.mDesignator.mInfo IS Types.PVariableRef) THEN
         OR (e.mDesignator.mInfo IS Types.PVariableRef) THEN
         result := e;
         result := e;
     ELSE
     ELSE
-        result := makeExpression(e.mDesignator.mRefCode(e.mDesignator.mCode),
-                                 e.mType,
-                                 NIL,
-                                 undefined);
+        result := makeSimpleExpression(e.mDesignator.mRefCode(e.mDesignator.mCode),
+                                       e.mType);
     END;
     END;
     RETURN result
     RETURN result
 END refExpression;
 END refExpression;

+ 4 - 4
src/operator.js

@@ -27,8 +27,8 @@ function makeBinary(op, code, precedence, resultPrecedence, resultType){
     return function(left, right, context){
     return function(left, right, context){
         var leftValue = left.constValue();
         var leftValue = left.constValue();
         var rightValue = right.constValue();
         var rightValue = right.constValue();
-        var value = (leftValue !== undefined && rightValue !== undefined)
-            ? op(leftValue, rightValue) : undefined;
+        var value = (leftValue && rightValue)
+            ? Code.makeNumberConst(op(leftValue.value, rightValue.value)) : undefined;
 
 
         var leftCode = Code.adjustPrecedence(Code.derefExpression(left), precedence);
         var leftCode = Code.adjustPrecedence(Code.derefExpression(left), precedence);
 
 
@@ -45,8 +45,8 @@ function makeUnary(op, code){
     return function(e){
     return function(e){
         var type = e.type();
         var type = e.type();
         var value = e.constValue();
         var value = e.constValue();
-        if (value !== undefined)
-            value = op(value, type) ;
+        if (value)
+            value = Code.makeNumberConst(op(value.value, type));
         var expCode = code + Code.adjustPrecedence(Code.derefExpression(e), precedence.unary);
         var expCode = code + Code.adjustPrecedence(Code.derefExpression(e), precedence.unary);
         return Code.makeExpression(expCode, type, undefined, value);
         return Code.makeExpression(expCode, type, undefined, value);
     };
     };

+ 7 - 7
src/procedure.js

@@ -197,13 +197,13 @@ function setBitImpl(name, bitOp){
     function operator(x, y){
     function operator(x, y){
         var value = y.constValue();
         var value = y.constValue();
         var valueCode;
         var valueCode;
-        if (value === undefined)
+        if (!value)
             valueCode = op.lsl(Code.makeExpression("1"), y).code();
             valueCode = op.lsl(Code.makeExpression("1"), y).code();
         else {
         else {
-            if (value < 0 || value > 31)
-                throw new Errors.Error("value (0..31) expected as a second argument of " + name + ", got " + value);
-            var comment = "bit: " + (y.isTerm() ? value : Code.adjustPrecedence(y, precedence.shift));
-            value = 1 << value;
+            if (value.value < 0 || value.value > 31)
+                throw new Errors.Error("value (0..31) expected as a second argument of " + name + ", got " + value.value);
+            var comment = "bit: " + (y.isTerm() ? value.value : Code.adjustPrecedence(y, precedence.shift));
+            value = 1 << value.value;
             valueCode = value + "/*" + comment + "*/";
             valueCode = value + "/*" + comment + "*/";
         }
         }
         return bitOp(Code.adjustPrecedence(x, precedence.assignment), valueCode);
         return bitOp(Code.adjustPrecedence(x, precedence.assignment), valueCode);
@@ -233,7 +233,7 @@ function incImpl(name, unary, op){
             valueCode = y.code();
             valueCode = y.code();
         else {
         else {
             var comment = y.isTerm() ? "" : "/*" + y.code() + "*/";
             var comment = y.isTerm() ? "" : "/*" + y.code() + "*/";
-            valueCode = value + comment;
+            valueCode = value.value + comment;
         }
         }
         return op(x.code(), valueCode);
         return op(x.code(), valueCode);
     }
     }
@@ -489,7 +489,7 @@ exports.predefined = [
                     var code = Code.adjustPrecedence(e, precedence.conditional) + " ? 1 : 0";
                     var code = Code.adjustPrecedence(e, precedence.conditional) + " ? 1 : 0";
                     var value = e.constValue();
                     var value = e.constValue();
                     if (value !== undefined)
                     if (value !== undefined)
-                        value = value ? 1 : 0;
+                        value = Code.makeNumberConst(value.value ? 1 : 0);
                     this.__callExpression = Code.makeExpressionWithPrecedence(
                     this.__callExpression = Code.makeExpressionWithPrecedence(
                         code, basicTypes.integer, undefined, value, precedence.conditional);
                         code, basicTypes.integer, undefined, value, precedence.conditional);
                 }
                 }