2
0
Vladislav Folts 10 жил өмнө
parent
commit
96b2cfd2d1

BIN
bin/compiled.zip


+ 2 - 14
src/context.js

@@ -69,23 +69,11 @@ function escapeString(s){
 exports.String = ChainedContext.extend({
 exports.String = ChainedContext.extend({
     init: function StringContext(context){
     init: function StringContext(context){
         ChainedContext.prototype.init.call(this, context);
         ChainedContext.prototype.init.call(this, context);
-        this.__result = undefined;
     },
     },
-    handleString: function(s){this.__result = s;},
-    toStr: function(s){return s;},
     endParse: function(){
     endParse: function(){
-        var s = this.toStr(this.__result);
+        var s = this.attributes.str;
         this.parent().handleConst(new Type.String(s), Code.makeStringConst(s), escapeString(s));
         this.parent().handleConst(new Type.String(s), Code.makeStringConst(s), escapeString(s));
-        }
-});
-
-exports.Char = exports.String.extend({
-    init: function CharContext(context){
-        exports.String.prototype.init.call(this, context);
-        this.__result = "";
-    },
-    handleChar: function(c){this.__result += String.fromCharCode(c);},
-    toStr: function(s){return String.fromCharCode(parseInt(s, 16));}
+    }
 });
 });
 
 
 exports.BaseType = ChainedContext.extend({
 exports.BaseType = ChainedContext.extend({

+ 1 - 5
src/grammar.js

@@ -6,8 +6,6 @@ var Parser = require("parser.js");
 var Class = require("rtl.js").Class;
 var Class = require("rtl.js").Class;
 
 
 var literal = Parser.literal;
 var literal = Parser.literal;
-var digit = Lexer.digit;
-var hexDigit = Lexer.hexDigit;
 var point = Lexer.point;
 var point = Lexer.point;
 
 
 var and = Parser.and;
 var and = Parser.and;
@@ -69,9 +67,7 @@ var variableDeclaration = context(and(identList, ":", type), contexts.variableDe
 var integer = context(Lexer.integer, Context.Integer);
 var integer = context(Lexer.integer, Context.Integer);
 var real = context(Lexer.real, Context.Real);
 var real = context(Lexer.real, Context.Real);
 var number = or(real, integer);
 var number = or(real, integer);
-
-var string = or(context(Lexer.string, Context.String)
-              , context(and(digit, repeat(hexDigit), "X"), Context.Char));
+var string = context(Lexer.string, Context.String);
 
 
 var factor = context(
 var factor = context(
     or(string, 
     or(string, 

+ 0 - 2
src/ob/Context.ob

@@ -2,9 +2,7 @@ MODULE Context;
 IMPORT OberonRtl, Object, ScopeBase;
 IMPORT OberonRtl, Object, ScopeBase;
 TYPE
 TYPE
     Type* = RECORD
     Type* = RECORD
-        handleChar*:    PROCEDURE(c: CHAR);
         handleLiteral*: PROCEDURE(s: STRING);
         handleLiteral*: PROCEDURE(s: STRING);
-        handleString*:  PROCEDURE(s: STRING);
         handleIdent*:   PROCEDURE(s: STRING);
         handleIdent*:   PROCEDURE(s: STRING);
         qualifyScope*:  PROCEDURE(scope: ScopeBase.PType): STRING;
         qualifyScope*:  PROCEDURE(scope: ScopeBase.PType): STRING;
         
         

+ 1 - 0
src/ob/ContextHierarchy.ob

@@ -19,6 +19,7 @@ TYPE
     Attributes* = RECORD
     Attributes* = RECORD
         int*: INTEGER;
         int*: INTEGER;
         real*: REAL;
         real*: REAL;
+        str*: STRING;
     END;
     END;
 
 
     Node* = RECORD
     Node* = RECORD

+ 49 - 49
src/ob/Lexer.ob

@@ -25,27 +25,12 @@ TYPE
 
 
 PROCEDURE isDigit(c: CHAR): BOOLEAN;
 PROCEDURE isDigit(c: CHAR): BOOLEAN;
     RETURN (c >= "0") & (c <= "9")
     RETURN (c >= "0") & (c <= "9")
-END isDigit;
+END;
 
 
 PROCEDURE isLetter(c: CHAR): BOOLEAN;
 PROCEDURE isLetter(c: CHAR): BOOLEAN;
     RETURN ((c >= "a") & (c <= "z")) OR ((c >= "A") & (c <= "Z"))
     RETURN ((c >= "a") & (c <= "z")) OR ((c >= "A") & (c <= "Z"))
 END;
 END;
 
 
-PROCEDURE digit*(VAR stream: Stream.Type; context: Context.Type): BOOLEAN;
-VAR
-    result: BOOLEAN;
-    c: CHAR;
-BEGIN
-    IF ~Stream.eof(stream) THEN
-        c := Stream.getChar(stream);
-        IF isDigit(c) THEN
-            context.handleChar(c);
-            result := TRUE;
-        END
-    END
-    RETURN result
-END digit;
-
 PROCEDURE peekSeparator(VAR stream: Stream.Type): BOOLEAN;
 PROCEDURE peekSeparator(VAR stream: Stream.Type): BOOLEAN;
 BEGIN
 BEGIN
     result <- TRUE;
     result <- TRUE;
@@ -196,18 +181,9 @@ BEGIN
     RETURN result;
     RETURN result;
 END;
 END;
 
 
-PROCEDURE hexDigit*(VAR stream: Stream.Type; context: Context.Type): BOOLEAN;
-VAR
-    result: BOOLEAN;
-    c: CHAR;
-BEGIN
-    c := Stream.getChar(stream);
-    IF isDigit(c) OR ((c >= "A") & (c <= "F")) THEN
-        context.handleChar(c);
-        result := TRUE;
-    END
-    RETURN result
-END hexDigit;
+PROCEDURE isHexDigit(c: CHAR): BOOLEAN;
+    RETURN isDigit(c) OR ((c >= "A") & (c <= "F"));
+END;
 
 
 PROCEDURE point*(VAR stream: Stream.Type; context: Context.Type): BOOLEAN;
 PROCEDURE point*(VAR stream: Stream.Type; context: Context.Type): BOOLEAN;
 VAR result: BOOLEAN;
 VAR result: BOOLEAN;
@@ -222,31 +198,55 @@ BEGIN
     RETURN result;
     RETURN result;
 END;
 END;
 
 
-PROCEDURE string*(VAR stream: Stream.Type; context: Context.Type): BOOLEAN;
-VAR
-    result: BOOLEAN;
-    c: CHAR;
-    s: STRING;
+PROCEDURE string*(VAR stream: Stream.Type; VAR context: ContextHierarchy.Node): BOOLEAN;
+
+    PROCEDURE quotedString();
+    VAR
+        c: CHAR;
+        s: STRING;
+    BEGIN
+        IF ~Stream.eof(stream) THEN
+            c := Stream.getChar(stream);
+            WHILE (c # quote) & ~Stream.eof(stream) DO
+                IF c # quote THEN
+                    s := s + String.fromChar(c);
+                END;
+                c := Stream.getChar(stream);
+            END;
+        ELSE
+            c := 0X;
+        END;
+        
+        IF c # quote THEN
+            Errors.raise("unexpected end of string");
+        END;
+        
+        context.attributes.str := s;
+    END;    
+
+    PROCEDURE hexString(firstChar: CHAR): BOOLEAN;
+    BEGIN
+        result <- FALSE;
+        s <- String.fromChar(firstChar);
+        WHILE ~Stream.eof(stream) & isHexDigit(Stream.peekChar(stream)) DO
+            s := s + String.fromChar(Stream.getChar(stream));
+        END;
+        IF ~Stream.eof(stream) & (Stream.getChar(stream) = "X") THEN
+            context.attributes.str := String.fromChar(CHR(String.parseHex(s)));
+            result := TRUE;
+        END;
+        RETURN result;
+    END;
+
 BEGIN
 BEGIN
+    result <- FALSE;
     IF ~Stream.eof(stream) THEN
     IF ~Stream.eof(stream) THEN
-        c := Stream.getChar(stream);
+        c <- Stream.getChar(stream);
         IF c = quote THEN
         IF c = quote THEN
-            IF ~Stream.eof(stream) THEN
-                c := Stream.getChar(stream);
-                WHILE (c # quote) & ~Stream.eof(stream) DO
-                    IF c # quote THEN
-                        s := s + String.fromChar(c);
-                    END;
-                    c := Stream.getChar(stream);
-                END;
-            ELSE
-                c := 0X;
-            END;
-            IF c # quote THEN
-                Errors.raise("unexpected end of string");
-            END;
-            context.handleString(s);
+            quotedString();
             result := TRUE;
             result := TRUE;
+        ELSIF isDigit(c) THEN
+            result := hexString(c);
         END
         END
     END
     END
     RETURN result
     RETURN result

+ 9 - 1
src/ob/String.ob

@@ -22,7 +22,15 @@ VAR
     result: REAL;
     result: REAL;
 BEGIN
 BEGIN
     JS.do("result = JS.Number(s)");
     JS.do("result = JS.Number(s)");
-    RETURN result
+    RETURN result;
+END;
+
+PROCEDURE parseHex*(s: STRING): INTEGER;
+VAR 
+    result: INTEGER;
+BEGIN
+    JS.do("result = JS.parseInt(s, 16)");
+    RETURN result;
 END;
 END;
 
 
 PROCEDURE indexOf*(self: STRING; c: CHAR): INTEGER;
 PROCEDURE indexOf*(self: STRING; c: CHAR): INTEGER;