ソースを参照

delete unintentionally committed

Vladislav Folts 11 年 前
コミット
2944856427

+ 0 - 4
snapshot/assert.js

@@ -1,4 +0,0 @@
-exports.ok = function(condition){
-	if (!condition)
-		throw new Error("assertion failed");
-}

+ 0 - 99
snapshot/cast.js

@@ -1,99 +0,0 @@
-"use strict";
-var Code = require("code.js");
-var Type = require("type.js");
-var ArrayType = Type.Array;
-var PointerType = Type.Pointer;
-var ProcedureType = Type.Procedure;
-
-function doNoting(context, e){return e;}
-
-function findBaseType(base, type){
-    while (type && type != base)
-        type = type.baseType();
-    return type;
-}
-
-function findPointerBaseType(pBase, pType){
-    if (!findBaseType(pBase.baseType(), pType.baseType()))
-        return undefined;
-    return pBase;
-}
-
-function matchesToNIL(t){
-    return t instanceof PointerType || t instanceof ProcedureType;
-}
-
-function areTypesMatch(t1, t2){
-    if (t1 == t2)
-        return true;
-    if (t1 instanceof PointerType && t2 instanceof PointerType)
-        return areTypesMatch(t1.baseType(), t2.baseType());
-    if (t1 instanceof ProcedureType && t2 instanceof ProcedureType)
-        return areProceduresMatch(t1, t2);
-    if (t1 == Type.nil && matchesToNIL(t2)
-        || t2 == Type.nil && matchesToNIL(t1))
-        return true;
-    return false;
-}
-
-function areProceduresMatch(p1, p2){
-    var args1 = p1.args();
-    var args2 = p2.args();
-    if (args1.length != args2.length)
-        return false;
-
-    for(var i = 0; i < args1.length; ++i){
-        var a1 = args1[i];
-        var a2 = args2[i];
-        if (a1.isVar != a2.isVar)
-            return false;
-        if (a1.type != p1 && a2.type != p2
-            &&!areTypesMatch(a1.type, a2.type))
-            return false;
-    }
-
-    var r1 = p1.result();
-    var r2 = p2.result();
-    if (r1 == p1 && r2 == p2)
-        return true;
-    return areTypesMatch(r1, r2);
-}
-
-function implicitCast(from, to){
-    if (from === to)
-        return doNoting;
-
-    if (from instanceof Type.String){
-        if (to === Type.basic.ch){
-            var v = from.asChar();
-            if (v !== undefined)
-                return function(){return new Code.Expression(v, to);};
-        }
-        else if (to instanceof Type.Array && to.elementsType() == Type.basic.ch)
-            return function(context, e){
-                return new Code.Expression(context.rtl().strToArray(e.code()), to);
-            };
-    }
-    else if (from instanceof ArrayType && to instanceof ArrayType)
-        return (to.length() === undefined || to.length() === from.length())
-            && implicitCast(from.elementsType(), to.elementsType());
-    else if (from instanceof PointerType && to instanceof PointerType){
-        if (findPointerBaseType(to, from))
-            return doNoting;
-    }
-    else if (from instanceof Type.Record && to instanceof Type.Record){
-        if (findBaseType(to, from))
-            return doNoting;
-    }
-    else if (from == Type.nil && matchesToNIL(to))
-        return doNoting;
-    else if (from instanceof ProcedureType && to instanceof ProcedureType){
-        if (areProceduresMatch(from, to))
-            return doNoting;
-    }
-    return undefined;
-}
-
-exports.areTypesMatch = areTypesMatch;
-exports.implicit = implicitCast;
-exports.findPointerBaseType = findPointerBaseType;

+ 0 - 148
snapshot/code.js

@@ -1,148 +0,0 @@
-"use strict";
-
-var Class = require("rtl.js").Class;
-var Type = require("type.js");
-
-var NullCodeGenerator = Class.extend({
-	init: function NullCodeGenerator(){},
-	write: function(){},
-    openScope: function(){},
-    closeScope: function(){},
-    getResult: function(){}
-});
-
-exports.Generator = Class.extend({
-	init: function CodeGenerator(){
-		this.__result = "";
-		this.__indent = "";
-	},
-	write: function(s){
-		this.__result += s.replace(/\n/g, "\n" + this.__indent);
-	},
-	openScope: function(){
-		this.__indent += "\t";
-		this.__result += "{\n" + this.__indent;
-	},
-	closeScope: function(ending){
-		this.__indent = this.__indent.substr(1);
-		this.__result = this.__result.substr(0, this.__result.length - 1) + "}";
-		if (ending)
-			this.write(ending);
-		else
-			this.write("\n");
-	},
-	getResult: function(){return this.__result;}
-});
-
-exports.SimpleGenerator = Class.extend({
-	init: function SimpleCodeGenerator(code){this.__result = code ? code : "";},
-	write: function(s){this.__result += s;},
-	result: function(){return this.__result;}
-});
-
-var Expression = Class.extend({
-	init: function Expression(code, type, designator, constValue, maxPrecedence){
-        this.__code = code;
-        this.__type = type;
-        this.__designator = designator;
-        this.__constValue = constValue;
-        this.__maxPrecedence = maxPrecedence;
-    },
-    code: function(){return this.__code;},
-    type: function(){return this.__type;},
-    designator: function(){return this.__designator;},
-    constValue: function(){return this.__constValue;},
-    maxPrecedence: function(){return this.__maxPrecedence;},
-    isTerm: function(){return !this.__designator && this.__maxPrecedence === undefined;},
-    deref: function(){
-        if (!this.__designator)
-            return this;
-        if (this.__type instanceof Type.Array || this.__type instanceof Type.Record)
-            return this;
-        var info = this.__designator.info();
-        if (!(info instanceof Type.VariableRef))
-            return this;
-        return new Expression(this.__code + ".get()", this.__type);
-    },
-    ref: function(){
-        if (!this.__designator)
-            return this;
-        
-        var info = this.__designator.info();
-        if (info instanceof Type.VariableRef)
-            return this;
-
-        return new Expression(this.__designator.refCode(), this.__type);
-    }
-});
-
-function adjustPrecedence(e, precedence){
-    var code = e.code();
-    if (e.maxPrecedence() > precedence)
-        code = "(" + code + ")";
-    return code;
-}
-
-function genExport(symbol){
-    if (symbol.isVariable())
-        return "function(){return " + symbol.id() + ";}";
-    if (symbol.isType()){
-        var type = symbol.info().type();
-        if (!(type instanceof Type.Record 
-              || (type instanceof Type.Pointer && !type.baseType().name())))
-            return undefined;
-    }
-    return symbol.id();
-}
-
-var ModuleGenerator = Class.extend({
-    init: function Code$ModuleGenerator(name, imports){
-        this.__name = name;
-        this.__imports = imports;
-    },
-    prolog: function(){
-        var result = "";            
-        var modules = this.__imports;
-        for(var name in modules){
-            var alias = modules[name];
-            if (result.length)
-                result += ", ";
-            result += alias;
-        }
-        return "var " + this.__name + " = function " + "(" + result + "){\n";
-    },
-    epilog: function(exports){
-        var result = "";
-        for(var access in exports){
-            var e = exports[access];
-            var code = genExport(e);
-            if (code){
-                if (result.length)
-                    result += ",\n";
-                result += "\t" + e.id() + ": " + code;
-            }
-        }
-        if (result.length)
-            result = "return {\n" + result + "\n}\n";
-        
-        result += "}(";
-
-        var modules = this.__imports;
-        var importList = "";
-        for(var name in modules){
-            if (importList.length)
-                importList += ", ";
-            importList += name;
-        }
-        result += importList;
-        result += ");\n";
-
-        return result;
-    }
-});
-
-exports.nullGenerator = new NullCodeGenerator();
-exports.Expression = Expression;
-exports.adjustPrecedence = adjustPrecedence;
-exports.genExport = genExport;
-exports.ModuleGenerator = ModuleGenerator;

+ 0 - 1843
snapshot/context.js

@@ -1,1843 +0,0 @@
-"use strict";
-
-var Cast = require("cast.js");
-var Code = require("code.js");
-var Errors = require("errors.js");
-var Lexer = require("lexer.js");
-var Module = require("module.js");
-var op = require("operator.js");
-var Parser = require("parser.js");
-var Procedure = require("procedure.js");
-var Class = require("rtl.js").Class;
-var Scope = require("scope.js");
-var Symbol = require("symbol.js");
-var Type = require("type.js");
-
-var basicTypes = Type.basic;
-
-function getSymbolAndScope(context, id){
-    var s = context.findSymbol(id);
-    if (!s)
-        throw new Errors.Error(
-            context instanceof Type.Module
-                ? "identifier '" + id + "' is not exported by module '" + context.name() + "'"
-                : "undeclared identifier: '" + id + "'");
-    return s;
-}
-
-function getSymbol(context, id){
-    return getSymbolAndScope(context, id).symbol();
-}
-
-function unwrapTypeId(type){
-    if (!(type instanceof Type.TypeId))
-        throw new Errors.Error("type name expected");
-    return type;
-}
-
-function unwrapType(type){
-    return unwrapTypeId(type).type();
-}
-
-function getTypeSymbol(context, id){
-    return unwrapType(getSymbol(context, id).info());
-}
-
-function throwTypeMismatch(from, to){
-    throw new Errors.Error("type mismatch: expected '" + to.description() +
-                           "', got '" + from.description() + "'");
-}
-
-function checkTypeMatch(from, to){
-    if (!Cast.areTypesMatch(from, to))
-        throwTypeMismatch(from, to);
-}
-
-function checkImplicitCast(from, to){
-    var result = Cast.implicit(from, to);
-    if (!result)
-        throwTypeMismatch(from, to);
-    return result;
-}
-
-function promoteTypeInExpression(e, type){
-    var fromType = e.type();
-    if (type == Type.basic.ch && fromType instanceof Type.String){
-        var v = fromType.asChar();
-        if (v !== undefined)
-            return new Code.Expression(v, type);
-    }
-    return e;
-}
-
-function promoteExpressionType(context, left, right){
-    var rightType = right.type();
-    if (!left)
-        return right;
-
-    var leftType = left.type();
-    if (rightType === undefined)
-        return right;
-    
-    return checkImplicitCast(rightType, leftType)(context, right);
-}
-
-function checkTypeCast(from, to, msg){
-    if (from instanceof Type.Pointer)
-        from = from.baseType();
-    if (to instanceof Type.Pointer)
-        to = to.baseType();
-
-    var t = to.baseType();
-    while (t && t != from)
-        t = t.baseType();
-    if (!t)
-        throw new Errors.Error(msg + ": '" + to.description()
-                             + "' is not an extension of '" + from.description() + "'");
-}
-
-var ChainedContext = Class.extend({
-    init: function ChainedContext(parent){this.__parent = parent;},
-    parent: function(){return this.__parent;},
-    codeGenerator: function(){return this.__parent.codeGenerator();},
-    findSymbol: function(id){return this.__parent.findSymbol(id);},
-    currentScope: function(s){return this.__parent.currentScope();},
-    pushScope: function(scope){this.__parent.pushScope(scope);},
-    popScope: function(){this.__parent.popScope();},
-    setType: function(type){this.__parent.setType(type);},
-    setDesignator: function(d){this.__parent.setDesignator(d);},
-    handleExpression: function(e){this.__parent.handleExpression(e);},
-    handleLiteral: function(s){this.__parent.handleLiteral(s);},
-    handleConst: function(type, value, code){this.__parent.handleConst(type, value, code);},
-    genTypeName: function(){return this.__parent.genTypeName();},
-    genVarName: function(id){return this.__parent.genVarName(id);},
-    qualifyScope: function(scope){return this.__parent.qualifyScope(scope);},
-    rtl: function(){return this.__parent.rtl();}
-});
-
-exports.Integer = ChainedContext.extend({
-    init: function IntegerContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        this.__result = "";
-        this.__isHex = false;
-    },
-    isLexem: function(){return true;},
-    handleChar: function(c){this.__result += c;},
-    handleLiteral: function(){this.__isHex = true;},
-    toInt: function(s){return parseInt(this.__result, 10);},
-    endParse: function(){
-        var n = this.toInt();
-        this.parent().handleConst(basicTypes.integer, n, n.toString());
-    }
-});
-
-exports.HexInteger = exports.Integer.extend({
-    init: function HexIntegerContext(context){
-        exports.Integer.prototype.init.call(this, context);
-    },
-    toInt: function(s){return parseInt(this.__result, 16);}
-});
-
-exports.Real = ChainedContext.extend({
-    init: function RealContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        this.__result = "";
-    },
-    isLexem: function(){return true;},
-    handleChar: function(c){this.__result += c;},
-    handleLiteral: function(s){
-        if (s == "D") // LONGREAL
-            s = "E";
-        this.__result += s;
-    },
-    endParse: function(){
-        var n = Number(this.__result);
-        this.parent().handleConst(basicTypes.real, n, n.toString());
-    }
-});
-
-function escapeString(s){
-    var result = "\"";
-    for(var i = 0; i < s.length; ++i){
-        var c = s[i];
-        if (c == '"')
-            result += "\\\"";
-        else
-            result += s[i];
-    }
-    return result + "\"";
-}
-
-exports.String = ChainedContext.extend({
-    init: function StringContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        this.__result = undefined;
-    },
-    handleString: function(s){this.__result = s;},
-    toStr: function(s){return s;},
-    endParse: function(){
-        var s = this.toStr(this.__result);
-        this.parent().handleConst(new Type.String(s), 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 += c;},
-    toStr: function(s){return String.fromCharCode(parseInt(s, 16));}
-});
-
-exports.BaseType = ChainedContext.extend({
-    init: function BaseTypeContext(context){
-        ChainedContext.prototype.init.call(this, context);
-    },
-    handleSymbol: function(s){
-        this.parent().setBaseType(unwrapType(s.symbol().info()));
-    }
-});
-
-var DesignatorInfo = Class.extend({
-    init: function(code, refCode, type, info, scope){
-        this.__code = code;
-        this.__refCode = refCode;
-        this.__type = type;
-        this.__info = info;
-        this.__scope = scope;
-    },
-    code: function(){return this.__code;},
-    refCode: function(){return this.__refCode(this.__code);},
-    type: function(){return this.__type;},
-    info: function(){return this.__info;},
-    scope: function(){return this.__scope;}
-});
-
-exports.QualifiedIdentificator = ChainedContext.extend({
-    init: function QualifiedIdentificator(context){
-        ChainedContext.prototype.init.call(this, context);
-        this.__module = undefined;
-        this.__id = undefined;
-        this.__code = "";
-    },
-    setIdent: function(id){
-        this.__id = id;
-    },
-    handleLiteral: function(){
-        var s = getSymbol(this, this.__id);
-        if (!s.isModule())
-            return false; // stop parsing
-        this.__module = s.info();
-        this.__code = this.__id + ".";
-        return undefined;
-    },
-    endParse: function(){
-        var s = getSymbolAndScope(this.__module ? this.__module : this, this.__id);
-        var code = this.__code + this.__id;
-        if (this.__module && s.symbol().isVariable())
-            code += "()";
-        this.parent().handleSymbol(s, code);
-    }
-});
-
-var Identdef = Class.extend({
-    init: function Identdef(id, exported){
-        this.__id = id;
-        this.__exported = exported;
-    },
-    id: function(){return this.__id;},
-    exported: function(){return this.__exported;}
-});
-
-exports.Identdef = ChainedContext.extend({
-    init: function IdentdefContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        this.__id = undefined;
-        this.__export = false;
-    },
-    setIdent: function(id){this.__id = id;},
-    handleLiteral: function(){this.__export = true;},
-    endParse: function(){
-        this.parent().handleIdentef(new Identdef(this.__id, this.__export));
-    }
-});
-
-exports.Designator = ChainedContext.extend({
-    init: function Context$Designator(context){
-        ChainedContext.prototype.init.call(this, context);
-        this.__currentType = undefined;
-        this.__info = undefined;
-        this.__scope = undefined;
-        this.__code = new Code.SimpleGenerator();
-        this.__indexExpression = undefined;
-        this.__derefCode = undefined;
-        this.__propCode = undefined;
-    },
-    handleSymbol: function(found, code){
-        this.__scope = found.scope();
-        var s = found.symbol();
-        var info = s.info();
-        if (info instanceof Type.Type || s.isType() || s.isProcedure())
-            this.__currentType = info;
-        else if (s.isVariable() || s.isConst())
-            this.__currentType = info.type();
-        this.__info = info;
-        this.__code.write(code);
-    },
-    setIdent: function(id){
-        var t = this.__currentType;
-        var isReadOnly = this.__info instanceof Type.Variable 
-                      && this.__info.isReadOnly();
-        if (t instanceof Type.Pointer){
-            this.__handleDeref();
-            isReadOnly = false;
-        }
-        else if (!(t instanceof Type.Record
-                || t instanceof Type.Module
-                || t instanceof Module.AnyType))
-            throw new Errors.Error("cannot designate '" + t.description() + "'");
-
-        this.__denote(id);
-        this.__info = new Type.Variable(this.__currentType, isReadOnly);
-        this.__scope = undefined;
-    },
-    codeGenerator: function(){return this.__code;},
-    handleExpression: function(e){this.__indexExpression = e;},
-    __handleIndexExpression: function(){
-        var e = this.__indexExpression;
-        var expType = e.type();
-        if (expType != basicTypes.integer)
-            throw new Errors.Error("'INTEGER' expression expected, got '" + expType.description() + "'");
-
-        var type = this.__currentType;
-        if (!(type instanceof Type.Array))
-            throw new Errors.Error("ARRAY expected, got '" + type.description() + "'");
-        var value = e.constValue();
-        if (value !== undefined && value >= type.length())
-            throw new Errors.Error("index out of bounds: maximum possible index is "
-                                 + (type.length() - 1)
-                                 + ", got " + value );
-
-        this.__currentType = type.elementsType();
-        this.__info = new Type.Variable(this.__currentType, this.__info.isReadOnly());
-    },
-    handleLiteral: function(s){
-        if (s == "]" || s == ","){
-            this.__handleIndexExpression();
-            var indexCode = this.__indexExpression.deref().code();
-            this.__propCode = indexCode;
-            this.__code = new Code.SimpleGenerator(this.__derefCode + "[" + indexCode + "]");
-            }
-        if (s == "[" || s == ","){
-            this.__derefCode = this.__code.result();
-            this.__code = new Code.SimpleGenerator();
-        }
-        else if (s == "^"){
-            this.__handleDeref();
-            this.__info = new Type.VariableRef(this.__currentType);
-        }
-    },
-    __handleDeref: function(){
-        if (!(this.__currentType instanceof Type.Pointer))
-            throw new Errors.Error("POINTER TO type expected, got '"
-                                 + this.__currentType.description() + "'");
-        this.__currentType = this.__currentType.baseType();
-        if (this.__currentType instanceof Type.NonExportedRecord)
-            throw new Errors.Error("POINTER TO non-exported RECORD type cannot be dereferenced");
-    },
-    handleTypeCast: function(type){
-        if (this.__currentType instanceof Type.Record){
-            if (!(this.__info instanceof Type.VariableRef))
-                throw new Errors.Error(
-                    "invalid type cast: a value variable and cannot be used in typeguard");
-            if (!(type instanceof Type.Record))
-                throw new Errors.Error(
-                    "invalid type cast: RECORD type expected as an argument of RECORD type guard, got '"
-                  + type.description() + "'");
-        }
-        else if (this.__currentType instanceof Type.Pointer)
-            if (!(type instanceof Type.Pointer))
-                throw new Errors.Error(
-                    "invalid type cast: POINTER type expected as an argument of POINTER type guard, got '"
-                  + type.description() + "'");
-
-        checkTypeCast(this.__currentType, type, "invalid type cast");
-
-        var baseType = type instanceof Type.Pointer ? type.baseType() : type;
-        var castName = this.qualifyScope(baseType.scope()) + baseType.cons();
-        var code = this.rtl().typeGuard(this.__code.result(), castName);
-        this.__code = new Code.SimpleGenerator(code);
-
-        this.__currentType = type;
-    },
-    __denote: function(id){
-        var t = this.__currentType;
-        var fieldType = t.findSymbol(id);
-        if (!fieldType)
-            throw new Errors.Error("Type '" + t.name() + "' has no '" + id + "' field");
-        this.__derefCode = this.__code.result();
-        this.__propCode = "\"" + id + "\"";
-        this.__code.write("." + id);
-        this.__currentType = fieldType;
-    },
-    endParse: function(){
-        var code = this.__code.result();
-        var self = this;
-        var refCode = function(code){return self.__makeRefCode(code);};
-        this.parent().setDesignator(
-            new DesignatorInfo(code, refCode, this.__currentType, this.__info, this.__scope));
-    },
-    __makeRefCode: function(code){
-        if ((this.__currentType instanceof Type.Array)
-            || (this.__currentType instanceof Type.Record)
-            || (this.__info instanceof Type.VariableRef))
-            return code;
-        if (this.__derefCode)
-            return this.rtl().makeRef(this.__derefCode, this.__propCode);
-        return "{set: function($v){" + code + " = $v;}, get: function(){return " + code + ";}}";
-    }
-});
-
-exports.Type = ChainedContext.extend({
-    init: function Context$Type(context){
-        ChainedContext.prototype.init.call(this, context);
-    },
-    handleSymbol: function(s){
-        this.parent().handleSymbol(s);
-    }
-});
-
-var HandleSymbolAsType = ChainedContext.extend({
-    init: function Context$HandleSymbolAsType(context){
-        ChainedContext.prototype.init.call(this, context);
-    },
-    handleSymbol: function(s){
-        this.setType(unwrapType(s.symbol().info()));
-    }
-});
-
-exports.FormalType = HandleSymbolAsType.extend({
-    init: function FormalType(context){
-        HandleSymbolAsType.prototype.init.call(this, context);
-        this.__arrayDimension = 0;
-    },
-    setType: function(type){           
-        for(var i = 0; i < this.__arrayDimension; ++i)
-            type = new Type.Array("ARRAY OF " + type.name()
-                               , undefined
-                               , type);
-        this.parent().setType(type);
-
-    },
-    handleLiteral: function(s){
-        if (s == "ARRAY")
-            ++this.__arrayDimension;
-    }
-});
-
-var ProcArg = Class.extend({
-    init: function(type, isVar){
-        this.type = type;
-        this.isVar = isVar;
-    },
-    description: function(){
-        return (this.isVar ? "VAR " : "") + this.type.description();
-    }
-});
-
-exports.FormalParameters = ChainedContext.extend({
-    init: function FormalParametersContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        this.__arguments = [];
-        this.__result = undefined;
-
-        var parent = this.parent();
-        this.__type = new Procedure.Type(parent.typeName());
-        parent.setType(this.__type);
-    },
-    addArgument: function(name, arg){
-        this.__arguments.push(arg);
-    },
-    handleSymbol: function(s){
-        var resultType = unwrapType(s.symbol().info());
-        if (resultType instanceof Type.Array)
-            throw new Errors.Error("the result type of a procedure cannot be an ARRAY");
-        if (resultType instanceof Type.Record)
-            throw new Errors.Error("the result type of a procedure cannot be a RECORD");
-        this.__result = resultType;
-    },
-    endParse: function(){
-        this.__type.define(this.__arguments, this.__result);
-    }
-});
-
-exports.FormalParametersProcDecl = exports.FormalParameters.extend({
-    init: function FormalParametersProcDeclContext(context){
-        exports.FormalParameters.prototype.init.call(this, context);
-    },
-    addArgument: function(name, arg){
-        exports.FormalParameters.prototype.addArgument.call(this, name, arg);
-        this.parent().addArgument(name, arg);
-    },
-    endParse: function(){
-        exports.FormalParameters.prototype.endParse.call(this);
-        this.parent().endParameters();
-    }
-});
-
-exports.ProcDecl = ChainedContext.extend({
-    init: function ProcDeclContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        this.__id = undefined;
-        this.__firstArgument = true;
-        this.__type = undefined;
-        this.__returnParsed = false;
-        this.__outerScope = this.parent().currentScope();
-    },
-    handleIdentef: function(id){
-        this.__id = id;
-        this.codeGenerator().write("\nfunction " + id.id() + "(");
-        this.parent().pushScope(new Scope.Procedure());
-    },
-    setIdent: function(id){
-        if (this.__id.id() != id)
-            throw new Errors.Error("mismatched procedure names: '" + this.__id.id()
-                                 + "' at the begining and '" + id + "' at the end");
-        this.codeGenerator().closeScope();
-        this.parent().popScope();
-    },
-    typeName: function(){return undefined;},
-    setType: function(type){
-        var procSymbol = new Symbol.Symbol(this.__id.id(), type);
-        this.__outerScope.addSymbol(procSymbol, this.__id.exported());
-        this.__type = type;
-    },
-    addArgument: function(name, arg){
-        if (name == this.__id.id())
-            throw new Errors.Error("argument '" + name + "' has the same name as procedure");
-        var readOnly = !arg.isVar && (arg.type instanceof Type.Array);
-        var v = arg.isVar ? new Type.VariableRef(arg.type)
-                          : new Type.Variable(arg.type, readOnly);
-        var s = new Symbol.Symbol(name, v);
-        this.currentScope().addSymbol(s);
-
-        var code = this.codeGenerator();
-        if (!this.__firstArgument)
-            code.write(", ");
-        else
-            this.__firstArgument = false;
-        code.write(name + "/*" + arg.description() + "*/");
-    },
-    endParameters: function(){
-        var code = this.codeGenerator();
-        code.write(")");
-        code.openScope();
-    },
-    handleReturn: function(type){
-        var result = this.__type.result();
-        if (!result)
-            throw new Errors.Error("unexpected RETURN in PROCEDURE declared with no result type");
-        if (!Cast.implicit(type, result))
-            throw new Errors.Error(
-                "RETURN '" + result.description() + "' expected, got '"
-                + type.description() + "'");
-        this.__returnParsed = true;
-    },
-    endParse: function(){
-        var result = this.__type.result();
-        if (result && !this.__returnParsed)
-            throw new Errors.Error("RETURN expected at the end of PROCEDURE declared with '"
-                                 + result.name() + "' result type");
-    }
-});
-
-exports.Return = ChainedContext.extend({
-    init: function ReturnContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        this.__type = undefined;
-        this.__code = new Code.SimpleGenerator();
-    },
-    codeGenerator: function(){return this.__code;},
-    handleExpression: function(e){
-        this.__type = e.type();
-        var designator = e.designator();
-        if (designator)
-            writeDerefDesignatorCode(designator, this.__code);
-    },
-    endParse: function(){
-        var parent = this.parent();
-        parent.codeGenerator().write("return " + this.__code.result() + ";\n");
-        parent.handleReturn(this.__type);
-    }
-});
-
-exports.ProcParams = HandleSymbolAsType.extend({
-    init: function Context$ProcParams(context){
-        HandleSymbolAsType.prototype.init.call(this, context);
-        this.__isVar = false;
-        this.__argNamesForType = [];
-    },
-    handleLiteral: function(s){
-        if (s == "VAR")
-            this.__isVar = true;
-    },
-    setIdent: function(id){ this.__argNamesForType.push(id);},
-    setType: function(type){
-        var names = this.__argNamesForType;
-        for(var i = 0; i < names.length; ++i){
-            var name = names[i];
-            this.parent().addArgument(name, new Procedure.Arg(type, this.__isVar));
-        }
-        this.__isVar = false;
-        this.__argNamesForType = [];
-    }
-});
-
-exports.PointerDecl = ChainedContext.extend({
-    init: function Context$PointerDecl(context){
-        ChainedContext.prototype.init.call(this, context);
-    },
-    handleSymbol: function(s){
-        var typeId = unwrapTypeId(s.symbol().info());
-        this.__setTypeId(typeId);
-    },
-    __setTypeId: function(typeId){
-        if (!(typeId instanceof Type.ForwardTypeId)){
-            var type = typeId.type();
-            if (!(type instanceof Type.Record))
-                throw new Errors.Error(
-                    "RECORD is expected as a POINTER base type, got '" + type.description() + "'");
-        }
-
-        var parent = this.parent();
-        var name = parent.isAnonymousDeclaration() 
-            ? undefined
-            : parent.genTypeName();
-        var pointerType = new Type.Pointer(name, typeId);
-        parent.setType(pointerType);
-    },
-    setType: function(type){
-        var typeId = new Type.TypeId(type);
-        this.currentScope().addType(typeId);
-        this.__setTypeId(typeId);
-    },
-    findSymbol: function(id){
-        var parent = this.parent();
-        var existing = parent.findSymbol(id);
-        if (existing)
-            return existing;
-
-        var scope = this.currentScope();
-        scope.addUnresolved(id);
-        var resolve = function(){return getSymbol(parent, id).info().type();};
-
-        return new Symbol.Found(
-            new Symbol.Symbol(id, new Type.ForwardTypeId(resolve)),
-            scope
-            );
-    },
-    isAnonymousDeclaration: function(){return true;},
-    exportField: function(field){
-        throw new Errors.Error( "cannot export anonymous RECORD field: '" + field + "'");
-    }
-});
-
-exports.ArrayDecl = HandleSymbolAsType.extend({
-    init: function Context$ArrayDecl(context){
-        HandleSymbolAsType.prototype.init.call(this, context);
-        this.__dimensions = undefined;
-    },
-    handleDimensions: function(dimensions){this.__dimensions = dimensions;},
-    setType: function(type){
-        var initializer = type instanceof Type.Array || type instanceof Type.Record
-            ? "function(){return " + type.initializer(this) + ";}"
-            : type.initializer(this);
-        var dimensions = "";
-        for(var i = this.__dimensions.length; i-- ;){
-            var length = this.__dimensions[i];
-            dimensions = length + (dimensions.length ? ", " + dimensions : "");
-            var arrayInit = !i
-                ? this.rtl().makeArray(dimensions + ", " + initializer)
-                : undefined;
-            type = new Type.Array("ARRAY OF " + type.name()
-                               , arrayInit
-                               , type
-                               , length);
-        }
-
-        this.__type = type;
-    },
-    isAnonymousDeclaration: function(){return true;},
-    endParse: function(){this.parent().setType(this.__type);}
-});
-
-exports.ArrayDimensions = ChainedContext.extend({
-    init: function ArrayDimensionsContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        this.__dimensions = [];
-    },
-    codeGenerator: function(){return Code.nullGenerator;},
-    handleExpression: function(e){
-        var type = e.type();
-        if (type !== basicTypes.integer)
-            throw new Errors.Error("'INTEGER' constant expression expected, got '" + type.description() + "'");
-        var value = e.constValue();
-        if (value === undefined)
-            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);
-    },
-    endParse: function(){
-        this.parent().handleDimensions(this.__dimensions);
-    }
-});
-
-var numericOpTypeCheck = {
-    expect: "numeric type",
-    check: function(t){return Type.numeric.indexOf(t) != -1;}
-};
-
-var intOpTypeCheck = {
-    expect: "INTEGER",
-    check: function(t){return t == basicTypes.integer;}
-};
-
-var orderOpTypeCheck = {
-    expect: "numeric type or CHAR or character array",
-    check: function(t){
-        return [basicTypes.integer, basicTypes.real, basicTypes.ch].indexOf(t) != -1
-            || (t instanceof Type.Array && t.elementsType() == basicTypes.ch);
-    }
-};
-
-var equalOpTypeCheck = {
-    expect: "numeric type or SET or BOOLEAN OR CHAR or character array or POINTER or PROCEDURE",
-    check: function(t){
-        return [basicTypes.integer, basicTypes.real, basicTypes.set, basicTypes.bool, basicTypes.ch].indexOf(t) != -1
-            || (t instanceof Type.Array && t.elementsType() == basicTypes.ch)
-            || t instanceof Type.Pointer
-            || t instanceof Type.Procedure
-            || t == Type.nil;
-    }
-};
-
-function assertOpType(type, check, literal){
-    if (!check.check(type))
-        throw new Errors.Error(
-            "operator '" + literal +
-            "' type mismatch: " + check.expect + " expected, got '" +
-            type.description() + "'");
-}
-
-function assertNumericOp(type, literal, op, intOp){
-    assertOpType(type, numericOpTypeCheck, literal);
-    return (intOp && type == basicTypes.integer)
-           ? intOp : op;
-}
-
-function assertIntOp(type, literal, op){
-    assertOpType(type, intOpTypeCheck, literal);
-    return op;
-}
-
-function useTypeInRelation(leftType, rightType){
-    if (leftType instanceof Type.Pointer && rightType instanceof Type.Pointer){
-        var type = Cast.findPointerBaseType(leftType, rightType);
-        if (!type)
-            type = Cast.findPointerBaseType(rightType, leftType);
-        if (type)
-            return type;
-    }
-    checkTypeMatch(rightType, leftType);
-    return leftType;
-}
-
-function relationOp(leftType, rightType, literal){
-    var o;
-    var check;
-    var type = useTypeInRelation(leftType, rightType);
-    switch (literal){
-        case "=":
-            o = op.equal;
-            check = equalOpTypeCheck;
-            break;
-        case "#":
-            o = op.notEqual;
-            check = equalOpTypeCheck;
-            break;
-        case "<":
-            o = op.less;
-            check = orderOpTypeCheck;
-            break;
-        case ">":
-            o = op.greater;
-            check = orderOpTypeCheck;
-            break;
-        case "<=":
-            if (type == basicTypes.set)
-                o = op.setInclL;
-            else {
-                o = op.eqLess;
-                check = orderOpTypeCheck;
-            }
-            break;
-        case ">=":
-            if (type == basicTypes.set)
-                o = op.setInclR;
-            else {
-                o = op.eqGreater;
-                check = orderOpTypeCheck;
-            }
-            break;
-        }
-    if (check)
-        assertOpType(type, check, literal);
-    return o;
-}
-
-exports.AddOperator = ChainedContext.extend({
-    init: function AddOperatorContext(context){
-        ChainedContext.prototype.init.call(this, context);
-    },
-    handleLiteral: function(s){
-        var parent = this.parent();
-        var type = parent.type();
-        var o;
-        if (s == "+")
-            o = (type == basicTypes.set) ? op.setUnion
-                                         : assertNumericOp(type, s, op.add, op.addInt);
-        else if (s == "-")
-            o = (type == basicTypes.set) ? op.setDiff
-                                         : assertNumericOp(type, s, op.sub, op.subInt);
-        else if (s == "OR"){
-            if (type != basicTypes.bool)
-                throw new Errors.Error("BOOLEAN expected as operand of 'OR', got '"
-                                     + type.description() + "'");
-            o = op.or;
-        }
-        if (o)
-            parent.handleBinaryOperator(o);
-    }
-});
-
-exports.MulOperator = ChainedContext.extend({
-    init: function MulOperatorContext(context){
-        ChainedContext.prototype.init.call(this, context);
-    },
-    handleLiteral: function(s){
-        var parent = this.parent();
-        var type = parent.type();
-        var o;
-        if (s == "*")
-            o = (type == basicTypes.set) ? op.setIntersection
-                                         : assertNumericOp(type, s, op.mul, op.mulInt);
-        else if (s == "/"){
-            if (type == basicTypes.set)
-                o = op.setSymmetricDiff;
-            else if (type == basicTypes.integer)
-                throw new Errors.Error("operator DIV expected for integer division");
-            else
-                o = assertNumericOp(type, s, op.div);
-        }
-        else if (s == "DIV")
-            o = assertIntOp(type, s, op.divInt);
-        else if (s == "MOD")
-            o = assertIntOp(type, s, op.mod);
-        else if (s == "&"){
-            if (type != basicTypes.bool)
-                throw new Errors.Error("BOOLEAN expected as operand of '&', got '"
-                                     + type.description() + "'");
-            o = op.and;
-        }
-
-        if (o)
-            parent.handleOperator(o);
-    }
-});
-
-function writeDerefDesignatorCode(designator, code){
-    var info = designator.info();
-    if (info instanceof Type.VariableRef)
-        code.write(".get()");
-}
-
-exports.Term = ChainedContext.extend({
-    init: function TermContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        this.__operator = undefined;
-        this.__expression = undefined;
-    },
-    type: function(){return this.__expression.type();},
-    setDesignator: function(d){
-        var value;
-        var info = d.info();
-        if (info instanceof Type.Const)
-            value = info.value();
-        this.handleExpression(
-            new Code.Expression(d.code(), d.type(), d, value));
-    },
-    handleOperator: function(o){this.__operator = o;},
-    handleConst: function(type, value, code){
-        this.handleExpression(new Code.Expression(
-            code, type, undefined, value));
-    },
-    handleFactor: function(e){
-        var type = e.type();
-        if (!type)
-            throw new Errors.Error("procedure returning no result cannot be used in an expression");
-        this.handleExpression(e);
-    },
-    endParse: function(){this.parent().handleTerm(this.__expression);},
-    handleExpression: function(e){
-        e = promoteExpressionType(this, this.__expression, e);
-        if (this.__operator)
-            e = this.__expression ? this.__operator(this.__expression, e)
-                                  : this.__operator(e);
-        this.__expression = e;
-    }
-});
-
-exports.Factor = ChainedContext.extend({
-    init: function FactorContext(context){
-        ChainedContext.prototype.init.call(this, context);
-    },
-    type: function(){return this.parent().type();},
-    handleLiteral: function(s){
-        var parent = this.parent();
-        if (s == "NIL")
-            parent.handleConst(Type.nil, undefined, "null");
-        else if (s == "TRUE")
-            parent.handleConst(basicTypes.bool, true, "true");
-        else if (s == "FALSE")
-            parent.handleConst(basicTypes.bool, false, "false");
-        else if (s == "~"){
-            parent.setType(basicTypes.bool);
-            parent.handleOperator(op.not);
-        }
-    },
-    handleFactor: function(e){this.parent().handleFactor(e);}
-});
-
-exports.Set = ChainedContext.extend({
-    init: function SetContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        this.__value = 0;
-        this.__expr = "";
-    },
-    handleElement: function(from, fromValue, to, toValue){
-        if (fromValue !== undefined && (!to || toValue !== undefined)){
-            if (to)
-                for(var i = fromValue; i <= toValue; ++i)
-                    this.__value |= 1 << i;
-            else
-                this.__value |= 1 << fromValue;
-        }
-        else{
-            if (this.__expr.length)
-                this.__expr += ", ";
-            if (to)
-                this.__expr += "[" + from + ", " + to + "]";
-            else
-                this.__expr += from;
-        }
-    },
-    endParse: function(){
-        var parent = this.parent();
-        if (!this.__expr.length)
-            parent.handleConst(basicTypes.set, this.__value, this.__value.toString());
-        else{
-            var code = this.rtl().makeSet(this.__expr);
-            if (this.__value)
-                code += " | " + this.__value;
-            var e = new Code.Expression(code, basicTypes.set);
-            parent.handleFactor(e);
-        }
-    }
-});
-
-exports.SetElement = ChainedContext.extend({
-    init: function SetElementContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        this.__from = undefined;
-        this.__fromValue = undefined;
-        this.__to = undefined;
-        this.__toValue = undefined;
-        this.__expr = new Code.SimpleGenerator();
-    },
-    codeGenerator: function(){return this.__expr;},
-    handleExpression: function(e){
-        var value = e.constValue();
-        if (!this.__from)
-            {
-            this.__from = this.__expr.result();
-            this.__fromValue = value;
-            this.__expr = new Code.SimpleGenerator();
-            }
-        else{
-            this.__to = this.__expr.result();
-            this.__toValue = value;
-        }
-    },
-    endParse: function(){
-        this.parent().handleElement(this.__from, this.__fromValue, this.__to, this.__toValue);
-    }
-});
-
-function constValueCode(value){
-    if (typeof value == "string")
-        return escapeString(value);
-    return value.toString();
-}
-
-exports.SimpleExpression = ChainedContext.extend({
-    init: function SimpleExpressionContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        this.__unaryOperator = undefined;
-        this.__binaryOperator = undefined;
-        this.__type = undefined;
-        this.__exp = undefined;
-    },
-    handleTerm: function(e){
-        var type = e.type();
-        this.setType(type);
-
-        var o;
-        switch(this.__unaryOperator){
-            case "-":
-                o = (type == basicTypes.set) ? op.setComplement
-                                             : assertNumericOp(type, this.__unaryOperator, op.negate);
-                break;
-            case "+":
-                o = assertNumericOp(type, this.__unaryOperator, op.unaryPlus);
-                break;
-            }
-        if (o){
-            this.__exp = o(e);
-            this.__unaryOperator = undefined;
-        }
-        else
-            this.__exp = this.__exp ? this.__binaryOperator(this.__exp, e) : e;
-    },
-    handleLiteral: function(s){this.__unaryOperator = s;},
-    type: function(){return this.__type;},
-    setType: function(type){
-        if (type === undefined || this.__type === undefined)
-            this.__type = type;
-        else
-            checkImplicitCast(type, this.__type);
-    },
-    handleBinaryOperator: function(o){this.__binaryOperator = o;},
-    endParse: function(){
-        this.parent().handleSimpleExpression(this.__exp);
-    }
-});
-
-exports.Expression = ChainedContext.extend({
-    init: function ExpressionContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        this.__relation = undefined;
-        this.__expression = undefined;
-    },
-    handleSimpleExpression: function(e){
-        if (!this.__expression){
-            this.__expression = e;
-            return;
-        }
-
-        var leftExpression = this.__expression;
-        var leftType = leftExpression.type();
-        var leftCode = leftExpression.code();
-        var rightExpression = e;
-        var rightType = rightExpression.type();
-        var rightCode = rightExpression.code();
-        var code;
-
-        if (this.__relation == "IN"){
-            if (leftType != basicTypes.integer)
-                throw new Errors.Error("'INTEGER' expected as an element of SET, got '" + leftType.name() + "'");
-            checkImplicitCast(rightType, basicTypes.set);
-
-            code = "1 << " + leftCode + " & " + rightCode;
-        }
-        else if (this.__relation == "IS"){
-            if (!(leftType instanceof Type.Pointer))
-                throw new Errors.Error("POINTER to type expected before 'IS'");
-
-            rightType = unwrapType(rightType);
-            if (!(rightType instanceof Type.Record))
-                throw new Errors.Error("RECORD type expected after 'IS'");
-
-            checkTypeCast(leftType, rightType, "invalid type test");
-
-            code = leftCode + " instanceof " + rightCode;
-        }
-        else {
-            leftExpression = promoteTypeInExpression(leftExpression, rightType);
-            rightExpression = promoteTypeInExpression(rightExpression, leftType);
-            leftCode = leftExpression.code();
-            rightCode = rightExpression.code();
-            //checkImplicitCast(rightExpression.type(), leftExpression.type());
-        }
-
-        var value;
-        if (!code){
-            var o = relationOp(leftExpression.type(), rightExpression.type(), this.__relation);
-            var oResult = o(leftExpression, rightExpression, this);
-            code = oResult.code();
-            value = oResult.constValue();
-        }
-
-        this.__expression = new Code.Expression(code, basicTypes.bool, undefined, value);
-    },
-    handleLiteral: function(relation){
-        this.__relation = relation;
-    },
-    codeGenerator: function(){return Code.nullGenerator;},
-    endParse: function(){
-        var parent = this.parent();
-        parent.codeGenerator().write(this.__expression.code());
-        parent.handleExpression(this.__expression);
-    }
-});
-
-function handleIfExpression(e){
-    var type = e.type();
-    if (type !== basicTypes.bool)
-        throw new Errors.Error("'BOOLEAN' expression expected, got '" + type.description() + "'");
-}
-
-var IfContextBase = ChainedContext.extend({
-    init: function(context){
-        ChainedContext.prototype.init.call(this, context);
-    },
-    endParse: function(){
-        var gen = this.codeGenerator();
-        gen.write(")");
-        gen.openScope();
-    },
-    handleExpression: handleIfExpression
-});
-
-exports.If = IfContextBase.extend({
-    init: function IfContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        this.codeGenerator().write("if (");
-    }
-});
-
-exports.ElseIf = IfContextBase.extend({
-    init: function ElseIfContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        var gen = this.codeGenerator();
-        gen.closeScope();
-        gen.write("else if (");
-    }
-});
-
-exports.Else = ChainedContext.extend({
-    init: function ElseContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        var gen = this.codeGenerator();
-        gen.closeScope();
-        gen.write("else ");
-        gen.openScope();
-    }
-});
-
-exports.emitEndStatement = function(context){
-    context.codeGenerator().write(";\n");
-};
-
-exports.emitIfEnd = function(context){
-    context.codeGenerator().closeScope();
-};
-
-exports.Case = ChainedContext.extend({
-    init: function CaseContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        this.__type = undefined;
-        this.__firstCase = true;
-        this.genVarName("$c");
-        this.codeGenerator().write("$c = ");
-    },
-    handleExpression: function(e){
-        var type = e.type();
-        var gen = this.codeGenerator();
-        if (type instanceof Type.String){
-            var v = type.asChar();
-            if (v !== undefined){
-                gen.write(v);
-                type = basicTypes.ch;
-            }
-        }
-        if (type != basicTypes.integer && type != basicTypes.ch)
-            throw new Errors.Error("'INTEGER' or 'CHAR' expected as CASE expression");
-        this.__type = type;
-        gen.write(";\n");
-    },
-    beginCase: function(){
-        if (this.__firstCase)
-            this.__firstCase = false;
-        else
-            this.codeGenerator().write("else ");
-    },
-    handleLabelType: function(type){
-        if (type !== this.__type)
-            throw new Errors.Error(
-                "label must be '" + this.__type.name() + "' (the same as case expression), got '"
-                + type.name() + "'");
-    }
-});
-
-exports.CaseLabelList = ChainedContext.extend({
-    init: function CaseLabelListContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        this.__glue = "";
-    },
-    handleLabelType: function(type){this.parent().handleLabelType(type);},
-    handleRange: function(from, to){
-        if (!this.__glue)
-            this.parent().caseLabelBegin();
-
-        var cond = to === undefined
-            ? "$c === " + from
-            : "($c >= " + from + " && $c <= " + to + ")";
-        this.codeGenerator().write(this.__glue + cond);
-        this.__glue = " || ";
-    },
-    endParse: function(){this.parent().caseLabelEnd();}
-});
-
-exports.CaseLabel = ChainedContext.extend({
-    init: function CaseLabelContext(context){
-        ChainedContext.prototype.init.call(this, context);
-    },
-    caseLabelBegin: function(){
-        this.parent().beginCase();
-        this.codeGenerator().write("if (");
-    },
-    caseLabelEnd: function(){
-        var gen = this.codeGenerator();
-        gen.write(")");
-        gen.openScope();
-    },
-    handleLabelType: function(type){this.parent().handleLabelType(type);},
-    handleRange: function(from, to){this.parent().handleRange(from, to);},
-    endParse: function(){this.codeGenerator().closeScope();}
-});
-
-exports.CaseRange = ChainedContext.extend({
-    init: function CaseRangeContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        this.__from = undefined;
-        this.__to = undefined;
-    },
-    codeGenerator: function(){return Code.nullGenerator;}, // suppress any output
-    handleLabel: function(type, v){
-        this.parent().handleLabelType(type);
-        if (this.__from === undefined )
-            this.__from = v;
-        else
-            this.__to = v;
-    },
-    handleConst: function(type, value){
-        if (type instanceof Type.String){
-            value = type.asChar();
-            if (value === undefined)
-                throw new Errors.Error("single-character string expected");
-            type = basicTypes.ch;
-        }
-        this.handleLabel(type, value);
-    },
-    setIdent: function(id){
-        var s = getSymbol(this.parent(), id);
-        if (!s.isConst())
-            throw new Errors.Error("'" + id + "' is not a constant");
-        
-        var type = s.info().type();
-        if (type instanceof Type.String)
-            this.handleConst(type, undefined);
-        else
-            this.handleLabel(type, s.info().value());
-    },
-    endParse: function(){this.parent().handleRange(this.__from, this.__to);}
-});
-
-exports.While = ChainedContext.extend({
-    init: function WhileContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        var gen = this.codeGenerator();
-        gen.write("while (true)");
-        gen.openScope();
-        gen.write("if (");
-    },
-    handleExpression: handleIfExpression,
-    endParse: function(){
-        var gen = this.codeGenerator();
-        gen.write(")");
-        gen.openScope();
-    }
-});
-
-exports.emitWhileEnd = function(context){
-    var gen = context.codeGenerator();
-    gen.closeScope(" else break;\n");
-    gen.closeScope();
-};
-
-exports.Repeat = ChainedContext.extend({
-    init: function RepeatContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        var gen = context.codeGenerator();
-        gen.write("do ");
-        gen.openScope();
-    }
-});
-
-exports.Until = ChainedContext.extend({
-    init: function UntilContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        var gen = context.codeGenerator();
-        gen.closeScope(" while (");
-    },
-    handleExpression: handleIfExpression,
-    endParse: function(){this.codeGenerator().write(");\n");}
-});
-
-exports.For = ChainedContext.extend({
-    init: function ForContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        this.__var = undefined;
-        this.__initExprParsed = false;
-        this.__toExpr = new Code.SimpleGenerator();
-        this.__toParsed = false;
-        this.__by_parsed = false;
-        this.__by = undefined;
-    },
-    setIdent: function(id){
-        var s = getSymbol(this.parent(), id);
-        if (!s.isVariable())
-            throw new Errors.Error("'" + s.id() + "' is not a variable");
-        if (s.info().type() !== basicTypes.integer)
-            throw new Errors.Error(
-                "'" + s.id() + "' is a 'BOOLEAN' variable, 'FOR' control variable must be 'INTEGER'");
-        this.codeGenerator().write("for (" + id + " = ");
-        this.__var = id;
-    },
-    handleExpression: function(e){
-        var type = e.type();
-        var value = e.constValue();
-        if (type !== basicTypes.integer)
-            throw new Errors.Error(
-                !this.__initExprParsed
-                    ? "'INTEGER' expression expected to assign '" + this.__var
-                      + "', got '" + type.description() + "'"
-                    : !this.__toParsed
-                    ? "'INTEGER' expression expected as 'TO' parameter, got '" + type.description() + "'"
-                    : "'INTEGER' expression expected as 'BY' parameter, got '" + type.description() + "'"
-                    );
-        if (!this.__initExprParsed)
-            this.__initExprParsed = true;
-        else if (!this.__toParsed)
-            this.__toParsed = true;
-        else if ( value === undefined )
-            throw new Errors.Error("constant expression expected as 'BY' parameter");
-        else
-            this.__by = value;
-    },
-    codeGenerator: function(){
-        if (this.__initExprParsed && !this.__toParsed)
-            return this.__toExpr;
-        if (this.__toParsed && !this.__by_parsed)
-            return Code.nullGenerator; // suppress output for BY expression
-        
-        return this.parent().codeGenerator();
-    },
-    handleBegin: function(){
-        this.__by_parsed = true;
-
-        var relation = this.__by < 0 ? " >= " : " <= ";
-        var step = this.__by === undefined
-                            ? "++" + this.__var
-                            : this.__var + (this.__by < 0
-                                    ? " -= " + -this.__by
-                                    : " += " +  this.__by);
-        var s = "; " + this.__var + relation + this.__toExpr.result() + "; " + step + ")";
-        var gen = this.codeGenerator();
-        gen.write(s);
-        gen.openScope();
-    },
-    endParse: function(){this.codeGenerator().closeScope();}
-});
-
-exports.emitForBegin = function(context){context.handleBegin();};
-
-exports.CheckAssignment = ChainedContext.extend({
-    init: function Context$CheckAssignment(context){
-        ChainedContext.prototype.init.call(this, context);
-    },
-    handleLiteral: function(s){
-        if (s == "=")
-            throw new Errors.Error("did you mean ':=' (statement expected, got expression)?");
-    }
-});
-
-exports.Assignment = ChainedContext.extend({
-    init: function AssignmentContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        this.__left = undefined;
-    },
-    codeGenerator: function(){/*throw new Error("Test");*/ return Code.nullGenerator;},
-    setDesignator: function(d){
-        this.__left = new Code.Expression(d.code(), d.type(), d);
-    },
-    handleExpression: function(e){
-        this.parent().codeGenerator().write(op.assign(this.__left, e, this));
-    }
-});
-
-exports.ConstDecl = ChainedContext.extend({
-    init: function ConstDeclContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        this.__id = undefined;
-        this.__type = undefined;
-        this.__value = undefined;
-    },
-    handleIdentef: function(id){
-        this.__id = id;
-        this.codeGenerator().write("var " + id.id() + " = ");
-    },
-    handleExpression: function(e){
-        var value = e.constValue();
-        if (value === undefined)
-            throw new Errors.Error("constant expression expected");
-        this.__type = e.type();
-        this.__value = value;
-    },
-    endParse: function(){
-        var c = new Type.Const(this.__type, this.__value);
-        this.currentScope().addSymbol(new Symbol.Symbol(this.__id.id(), c), this.__id.exported());
-        this.codeGenerator().write(";\n");
-    }
-});
-
-function checkIfFieldCanBeExported(name, idents, hint){
-    for(var i = 0; i < idents.length; ++i){
-        var id = idents[i];
-        if (!id.exported())
-            throw new Errors.Error(
-                "field '" + name + "' can be exported only if " + hint + " '" +
-                id.id() + "' itself is exported too");
-    }
-}
-
-exports.VariableDeclaration = HandleSymbolAsType.extend({
-    init: function Context$VariableDeclaration(context){
-        HandleSymbolAsType.prototype.init.call(this, context);
-        this.__idents = [];
-        this.__type = undefined;
-    },
-    handleIdentef: function(id){this.__idents.push(id);},
-    exportField: function(name){
-        checkIfFieldCanBeExported(name, this.__idents, "variable");
-    },
-    setType: function(type){this.__type = type;},
-    typeName: function(){return undefined;},
-    isAnonymousDeclaration: function(){return true;},
-    endParse: function(){
-        var v = new Type.Variable(this.__type);
-        var idents = this.__idents;
-        var gen = this.codeGenerator();
-        for(var i = 0; i < idents.length; ++i){
-            var id = idents[i];
-            if (id.exported()
-                && (this.__type instanceof Type.Record
-                    || this.__type instanceof Type.Array))
-                throw new Errors.Error("only scalar type variables can be exported");
-            var varName = id.id();
-            this.currentScope().addSymbol(new Symbol.Symbol(varName, v), id.exported());
-            var t = v.type();
-            gen.write("var " + varName + " = " + t.initializer(this) + ";");
-        }
-
-        gen.write("\n");
-    }
-});
-
-exports.FieldListDeclaration = HandleSymbolAsType.extend({
-    init: function Context$FieldListDeclaration(context){
-        HandleSymbolAsType.prototype.init.call(this, context);
-        this.__idents = [];
-        this.__type = undefined;
-    },
-    typeName: function(){return undefined;},
-    handleIdentef: function(id) {this.__idents.push(id);},
-    exportField: function(name){
-        checkIfFieldCanBeExported(name, this.__idents, "field");
-    },
-    setType: function(type) {this.__type = type;},
-    isAnonymousDeclaration: function(){return true;},
-    endParse: function(){
-        var idents = this.__idents;
-        var parent = this.parent();
-        for(var i = 0; i < idents.length; ++i)
-            parent.addField(idents[i], this.__type);
-    }
-});
-
-function assertProcType(type){
-    if (!(type instanceof Type.Procedure) && !(type instanceof Module.AnyType))
-        throw new Errors.Error("PROCEDURE expected, got '" + type.description() + "'");
-}
-
-exports.ActualParameters = ChainedContext.extend({
-    init: function ActualParametersContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        this.parent().hasActualParameters();
-    }
-});
-
-var ProcedureCall = ChainedContext.extend({
-    init: function ProcedureCallContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        this.__type = undefined;
-        this.__procCall = undefined;
-        this.__code = new Code.SimpleGenerator();
-    },
-    setDesignator: function(d){
-        var type = d.type();
-        assertProcType(type);
-        this.__type = type;
-        this.__procCall = type.callGenerator(this, d.code());
-        this.__callExpression = undefined;
-    },
-    codeGenerator: function(){return this.__code;},
-    type: function(){return this.__type;},
-    hasActualParameters: function(){},
-    handleExpression: function(e){this.__procCall.handleArgument(e);},
-    callExpression: function(){return this.__callExpression;},
-    endParse: function(){this.__callExpression = this.__procCall.end();}
-});
-
-exports.StatementProcedureCall = ProcedureCall.extend({
-    init: function StatementProcedureCallContext(context){
-        ProcedureCall.prototype.init.call(this, context);
-    },
-    endParse: function(){
-        ProcedureCall.prototype.endParse.call(this);
-        var e = this.callExpression();
-        var type = e.type();
-        if  (type && !(type instanceof Module.AnyType ))
-            throw new Errors.Error("procedure returning a result cannot be used as a statement");
-        this.parent().codeGenerator().write(e.code());
-    }
-});
-
-exports.ExpressionProcedureCall = ProcedureCall.extend({
-    init: function ExpressionProcedureCall(context){
-        ProcedureCall.prototype.init.call(this, context);
-        this.__designator = undefined;
-        this.__hasActualParameters = false;
-    },
-    setDesignator: function(d){
-        this.__designator = d;
-    },
-    hasActualParameters: function(){
-        ProcedureCall.prototype.setDesignator.call(this, this.__designator);
-        this.__hasActualParameters = true;
-    },
-    endParse: function(){
-        var parent = this.parent();
-        if (this.__hasActualParameters){
-            ProcedureCall.prototype.endParse.call(this);
-            parent.handleFactor(this.callExpression());
-        }
-        else{
-            var d = this.__designator;
-            var info = d.info();
-            if (info instanceof Type.Procedure){
-                if (info instanceof Procedure.Std)
-                    throw new Errors.Error(info.description() + " cannot be referenced");
-                var scope = d.scope();
-                if (scope && scope.id() == "procedure")
-                    throw new Errors.Error("local procedure '" + d.code() + "' cannot be referenced");
-            }
-            parent.setDesignator(d);
-        }
-    }
-});
-
-function isTypeRecursive(type, base){
-    if (type == base)
-        return true;
-    if (type instanceof Type.Record){
-        if (isTypeRecursive(type.baseType(), base))
-            return true;
-        var fields = type.ownFields();
-        for(var fieldName in fields){
-            if (isTypeRecursive(fields[fieldName], base))
-                return true;
-        }
-    }
-    else if (type instanceof Type.Array)
-        return isTypeRecursive(type.elementsType(), base);
-    return false;
-}
-
-exports.RecordDecl = ChainedContext.extend({
-    init: function RecordDeclContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        var parent = this.parent();
-        var cons = parent.genTypeName();
-        var name = parent.isAnonymousDeclaration() ? undefined : cons;
-        this.__type = new Type.Record(name, cons, context.currentScope());
-        parent.setType(this.__type);
-        parent.codeGenerator().write("var " + cons + " = ");
-    },
-    addField: function(field, type){
-        if (isTypeRecursive(type, this.__type))
-            throw new Errors.Error("recursive field definition: '"
-                + field.id() + "'");
-        this.__type.addField(field, type);
-        if (field.exported())
-            this.parent().exportField(field.id());
-    },
-    setBaseType: function(type){
-        if (!(type instanceof Type.Record))
-            throw new Errors.Error(
-                "RECORD type is expected as a base type, got '"
-                + type.description()
-                + "'");
-        if (isTypeRecursive(type, this.__type))
-            throw new Errors.Error("recursive inheritance: '"
-                + this.__type.name() + "'");
-        this.__type.setBaseType(type);
-    },
-    endParse: function(){
-        var type = this.__type;
-        var baseType = type.baseType();
-        var gen = this.codeGenerator();
-        gen.write((baseType ? baseType.name() + ".extend" : this.rtl().extendId()) + "(");
-        gen.openScope();
-        gen.write("init: function " + this.__type.cons() + "()");
-        gen.openScope();
-        if (baseType)
-            gen.write(baseType.name() + ".prototype.init.call(this);\n");
-        var ownFields = type.ownFields();
-        for(var f in ownFields)
-            gen.write("this." + f + " = " + ownFields[f].initializer(this) + ";\n");
-
-        gen.closeScope();
-        gen.closeScope(");\n");
-    }
-});
-
-exports.TypeDeclaration = ChainedContext.extend({
-    init: function TypeDeclarationContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        this.__id = undefined;
-        this.__symbol = undefined;
-    },
-    handleIdentef: function(id){
-        var typeId = new Type.LazyTypeId();
-        var symbol = this.currentScope().addType(typeId, id);
-        this.__id = id;
-        this.__symbol = symbol;
-    },
-    setType: function(type){
-        this.__symbol.info().define(type);
-        this.currentScope().resolve(this.__symbol);
-    },
-    typeName: function(){return this.__id.id();},
-    genTypeName: function(){return this.__id.id();},
-    isAnonymousDeclaration: function(){return false;},
-    type: function(){return this.parent().type();},
-    exportField: function(name){
-        checkIfFieldCanBeExported(name, [this.__id], "record");
-    }
-});
-
-exports.TypeSection = ChainedContext.extend({
-    init: function TypeSection(context){
-        ChainedContext.prototype.init.call(this, context);
-    },
-    endParse: function(){
-        var unresolved = this.currentScope().unresolved();
-        if (unresolved.length)
-            throw new Errors.Error("no declaration found for '" + unresolved.join("', '") + "'");
-    }
-});
-
-exports.TypeCast = ChainedContext.extend({
-    init: function TypeCastContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        this.__type = undefined;
-    },
-    handleSymbol: function(s){
-        s = s.symbol();
-        if (!s.isType())
-            return; // this is not a type cast, may be procedure call
-        this.__type = s.info().type();
-    },
-    endParse: function(){
-        if (this.__type === undefined)
-            return false;
-        this.parent().handleTypeCast(this.__type);
-        return true;
-    }
-});
-
-exports.ModuleDeclaration = ChainedContext.extend({
-    init: function ModuleDeclarationContext(context){
-        ChainedContext.prototype.init.call(this, context);
-        this.__name = undefined;
-        this.__imports = {};
-        this.__moduleScope = undefined;
-        this.__moduleGen = undefined;
-    },
-    setIdent: function(id){
-        var parent = this.parent();
-        if (this.__name === undefined ) {
-            this.__name = id;
-            this.__moduleScope = new Scope.Module(id);
-            parent.pushScope(this.__moduleScope);
-        }
-        else if (id === this.__name){
-            var scope = parent.currentScope();
-            scope.strip();
-            var exports = scope.exports();
-            scope.module().info().defineExports(exports);
-            this.codeGenerator().write(this.__moduleGen.epilog(exports));
-        }
-        else
-            throw new Errors.Error("original module name '" + this.__name + "' expected, got '" + id + "'" );
-    },
-    findModule: function(name){
-        if (name == this.__name)
-            throw new Errors.Error("module '" + this.__name + "' cannot import itself");
-        return this.parent().findModule(name);
-    },
-    handleImport: function(modules){
-        var scope = this.currentScope();
-        var moduleAliases = {};
-        for(var i = 0; i < modules.length; ++i){
-            var s = modules[i];
-            var name = s.info().name();
-            this.__imports[name] = s;
-            scope.addSymbol(s);
-            moduleAliases[name] = s.id();
-        }
-        this.__moduleGen = this.parent().makeModuleGenerator(
-                this.__name,
-                moduleAliases);
-        this.codeGenerator().write(this.__moduleGen.prolog());
-    },
-    qualifyScope: function(scope){
-        if (scope != this.__moduleScope && scope instanceof Scope.Module)
-            return this.__imports[scope.module().id()].id() + ".";
-        return "";
-    }
-});
-
-var ModuleImport = ChainedContext.extend({
-    init: function ModuleImport(context){
-        ChainedContext.prototype.init.call(this, context);
-        this.__import = {};
-        this.__currentModule = undefined;
-        this.__currentAlias = undefined;
-    },
-    setIdent: function(id){
-        this.__currentModule = id;
-    },
-    handleLiteral: function(s){
-        if (s == ":=")
-            this.__currentAlias = this.__currentModule;
-        else if (s == ",")
-            this.__handleImport();
-    },
-    endParse: function(){
-        if (this.__currentModule)
-            this.__handleImport();
-
-        var modules = [];
-        var unresolved = [];
-        for(var alias in this.__import){
-            var moduleName = this.__import[alias];
-            var module = this.parent().findModule(moduleName);
-            if (!module)
-                unresolved.push(moduleName);
-            else
-                modules.push(new Symbol.Symbol(alias, module));
-        }
-        if (unresolved.length)
-            throw new Errors.Error("module(s) not found: " + unresolved.join(", "));
-        
-        this.parent().handleImport(modules);
-    },
-    __handleImport: function(){
-        var alias = this.__currentAlias;
-        if (!alias)
-            alias = this.__currentModule;
-        else
-            this.__currentAlias = undefined;
-        
-        for(var a in this.__import){
-            if (a == alias)
-                throw new Errors.Error("duplicated alias: '" + alias +"'");
-            if (this.__import[a] == this.__currentModule)
-                throw new Errors.Error("module already imported: '" + this.__currentModule +"'");
-        }
-        this.__import[alias] = this.__currentModule;
-    }
-});
-exports.ModuleImport = ModuleImport;
-
-exports.Context = Class.extend({
-    init: function Context(code, moduleGeneratorFactory, rtl, moduleResolver){
-        this.__code = code;
-        this.__moduleGeneratorFactory = moduleGeneratorFactory;
-        this.__scopes = [];
-        this.__gen = 0;
-        this.__vars = [];
-        this.__rtl = rtl;
-        this.__moduleResolver = moduleResolver;
-    },
-    genTypeName: function(){
-        ++this.__gen;
-        return "anonymous$" + this.__gen;
-    },
-    genVarName: function(id){
-        if (this.__vars.indexOf(id) === -1) {
-            this.__code.write("var " + id + ";\n");
-            this.__vars.push(id);
-        }
-    },
-    findSymbol: function(ident){
-        for(var i = this.__scopes.length; i--;){
-            var scope = this.__scopes[i];
-            var s = scope.findSymbol(ident);
-
-            if (s)
-                return new Symbol.Found(s, scope);
-        }
-        return undefined;
-    },
-    currentScope: function(){return this.__scopes[this.__scopes.length - 1];},
-    pushScope: function(scope){this.__scopes.push(scope);},
-    popScope: function(){this.__scopes.pop();},
-    handleExpression: function(){},
-    handleLiteral: function(){},
-    codeGenerator: function(){return this.__code;},
-    makeModuleGenerator: function(name, imports){
-        return this.__moduleGeneratorFactory(name, imports);
-    },
-    rtl: function(){return this.__rtl;},
-    findModule: function(name){
-        if (name == "JS"){
-            return new Module.JS();
-        }
-        return this.__moduleResolver ? this.__moduleResolver(name) : undefined;
-    }
-});

+ 0 - 20
snapshot/errors.js

@@ -1,20 +0,0 @@
-"use strict";
-/*
-do not use Class here - IE8 does not understand overloeded toString method (using Class.extend).
-
-var Class = require("rtl.js").Class;
-
-exports.Error = Class.extend({
-	init: function CompileError(msg) {this.__msg = msg;},
-	toString: function(){return this.__msg;}
-});
-*/
-function CompileError(msg){
-    this.__msg = msg;
-}
-
-CompileError.prototype.toString = function(){
-    return this.__msg;
-};
-
-exports.Error = CompileError;

+ 0 - 199
snapshot/grammar.js

@@ -1,199 +0,0 @@
-"use strict";
-
-var Context = require("context.js");
-var Lexer = require("lexer.js");
-var Parser = require("parser.js");
-var Class = require("rtl.js").Class;
-
-var character = Lexer.character;
-var literal = Lexer.literal;
-var digit = Lexer.digit;
-var hexDigit = Lexer.hexDigit;
-var ident = Lexer.ident;
-var point = Lexer.point;
-var separator = Lexer.separator;
-
-var and = Parser.and;
-var or = Parser.or;
-var optional = Parser.optional;
-var repeat = Parser.repeat;
-
-var context = Parser.context;
-var emit = Parser.emit;
-var required = Parser.required;
-
-var qualident = context(and(optional(and(ident, ".")), ident),
-                        Context.QualifiedIdentificator);
-var identdef = context(and(ident, optional("*")),
-                       Context.Identdef);
-var selector = or(and(point, ident)
-                // break recursive declaration of expList
-                , and("[", function(stream, context){return expList(stream, context);}, "]")
-                , "^"
-                , context(and("(", qualident, ")"), Context.TypeCast)
-                );
-var designator = context(and(qualident, repeat(selector)), Context.Designator);
-var type = or(context(qualident, Context.Type),
-              function(stream, context){return strucType(stream, context);} // break recursive declaration of strucType
-             );
-var identList = and(identdef, repeat(and(",", identdef)));
-var variableDeclaration = context(and(identList, ":", type), Context.VariableDeclaration);
-
-var integer = or(context(and(digit, repeat(hexDigit), "H", separator), Context.HexInteger)
-               , context(and(digit, repeat(digit), separator), Context.Integer));
-
-var scaleFactor = and(or("E", "D"), optional(or("+", "-")), digit, repeat(digit));
-var real = context(and(digit, repeat(digit), point, repeat(digit), optional(scaleFactor))
-                 , Context.Real);
-
-var number = or(real, integer);
-
-var string = or(context(Lexer.string, Context.String)
-              , context(and(digit, repeat(hexDigit), "X"), Context.Char));
-
-var factor = context(
-    or(string, number, "NIL", "TRUE", "FALSE"
-     , function(stream, context){return set(stream, context);} // break recursive declaration of set
-     , context(and(designator
-                 // break recursive declaration of actualParameters
-                 , optional(function(stream, context){return actualParameters(stream, context);})
-                  )
-             , Context.ExpressionProcedureCall)
-     , and("(", function(stream, context){return expression(stream, context);}
-         , required(")", "no matched ')'"))
-     , and("~", function(stream, context){
-                    return factor(stream, context);}) // break recursive declaration of factor
-     )
-    , Context.Factor);
-var addOperator = context(or("+", "-", "OR"), Context.AddOperator);
-var mulOperator = context(or("*", "/", "DIV", "MOD", "&"), Context.MulOperator);
-var term = context(and(factor, repeat(and(mulOperator, factor))), Context.Term);
-var simpleExpression = context(
-        and(optional(or("+", "-"))
-          , term
-          , repeat(and(addOperator, term)))
-      , Context.SimpleExpression);
-var relation = or("=", "#", "<=", "<", ">=", ">", "IN", "IS");
-var expression = context(and(simpleExpression, optional(and(relation, simpleExpression)))
-                       , Context.Expression);
-var constExpression = expression;
-
-var element = context(and(expression, optional(and("..", expression))), Context.SetElement);
-var set = and("{", context(optional(and(element, repeat(and(",", element)))), Context.Set)
-            , "}");
-
-var expList = and(expression, repeat(and(",", expression)));
-var actualParameters = and("(", context(optional(expList), Context.ActualParameters), ")");
-var procedureCall = context(and(designator, optional(actualParameters))
-                          , Context.StatementProcedureCall);
-
-var assignment = context(and(designator, context(or(":=", "="), Context.CheckAssignment)
-                       , required(expression, "expression expected"))
-                       , Context.Assignment);
-
-var statement = optional(or(
-                   emit(assignment, Context.emitEndStatement)
-                 , emit(procedureCall, Context.emitEndStatement)
-                   // break recursive declaration of ifStatement/caseStatement/whileStatement/repeatStatement
-                 , function(stream, context){return ifStatement(stream, context);}
-                 , function(stream, context){return caseStatement(stream, context);}
-                 , function(stream, context){return whileStatement(stream, context);}
-                 , function(stream, context){return repeatStatement(stream, context);}
-                 , function(stream, context){return forStatement(stream, context);}
-                 ));
-var statementSequence = and(statement, repeat(and(";", statement)));
-
-var ifStatement = and("IF", context(expression, Context.If), "THEN", statementSequence
-                    , repeat(and("ELSIF", context(expression, Context.ElseIf), "THEN", statementSequence))
-                    , optional(and("ELSE", context(statementSequence, Context.Else)))
-                    , emit("END", Context.emitIfEnd));
-
-var label = or(integer, string, ident);
-var labelRange = context(and(label, optional(and("..", label))), Context.CaseRange);
-var caseLabelList = context(and(labelRange, repeat(and(",", labelRange))), Context.CaseLabelList);
-var caseParser = optional(context(and(caseLabelList, ":", statementSequence), Context.CaseLabel));
-var caseStatement = and("CASE", context(and(expression
-                      , "OF", caseParser, repeat(and("|", caseParser)), "END")
-                      , Context.Case));
-
-var whileStatement = and("WHILE", context(expression, Context.While), "DO", statementSequence
-                       , repeat(and("ELSIF", context(expression, Context.ElseIf), "DO", statementSequence))
-                       , emit("END", Context.emitWhileEnd)
-                       );
-var repeatStatement = and("REPEAT", context(statementSequence, Context.Repeat)
-                        , "UNTIL", context(expression, Context.Until));
-
-var forStatement = context(and("FOR", ident, ":=", expression, "TO", expression
-                             , optional(and("BY", constExpression))
-                             , emit("DO", Context.emitForBegin)
-                             , statementSequence, required("END", "END expected (FOR)"))
-                         , Context.For);
-
-var fieldList = context(and(identList, ":", type), Context.FieldListDeclaration);
-var fieldListSequence = and(fieldList, repeat(and(";", fieldList)));
-
-var arrayType = and("ARRAY", context(and(
-                        context(and(constExpression, repeat(and(",", constExpression)))
-                              , Context.ArrayDimensions)
-                  , "OF", type), Context.ArrayDecl));
-
-var baseType = context(qualident, Context.BaseType);
-var recordType = and("RECORD", context(and(optional(and("(", baseType, ")")), optional(fieldListSequence)
-                                     , "END"), Context.RecordDecl));
-
-var pointerType = and("POINTER", "TO", context(type, Context.PointerDecl));
-
-var formalType = context(and(repeat(and("ARRAY", "OF")), qualident), Context.FormalType);
-var fpSection = and(optional(literal("VAR")), ident, repeat(and(",", ident)), ":", formalType);
-var formalParameters = and(
-          "("
-        , optional(context(and(fpSection, repeat(and(";", fpSection))), Context.ProcParams))
-        , required( ")" )
-        , optional(and(":", qualident)));
-
-var procedureType = and("PROCEDURE"
-                      , context(optional(formalParameters), Context.FormalParameters)
-                        );
-var strucType = or(arrayType, recordType, pointerType, procedureType);
-var typeDeclaration = context(and(identdef, "=", strucType), Context.TypeDeclaration);
-
-var procedureHeading = and("PROCEDURE"
-                         , identdef
-                         , context(optional(formalParameters), Context.FormalParametersProcDecl));
-var procedureDeclaration = context(
-      and(procedureHeading, ";"
-          // break recursive declaration of procedureBody
-        , function(stream, context){return procedureBody(stream, context);}
-        , ident)
-    , Context.ProcDecl);
-
-var constantDeclaration = context(and(identdef, "=", constExpression), Context.ConstDecl);
-
-var declarationSequence = and(optional(and("CONST", repeat(and(constantDeclaration, required(";")))))
-                            , optional(and("TYPE", context(repeat(and(typeDeclaration, required(";"))), Context.TypeSection)))
-                            , optional(and("VAR", repeat(and(variableDeclaration, required(";")))))
-                            , repeat(and(procedureDeclaration, ";")));
-var procedureBody = and(declarationSequence
-                      , optional(and("BEGIN", statementSequence))
-                      , optional(context(and("RETURN", expression), Context.Return))
-                      , required("END", "END expected (PROCEDURE)"));
-
-var imprt = and(ident, optional(and(":=", ident)));
-var importList = and("IMPORT", imprt, repeat(and(",", imprt)));
-var modul = context(and("MODULE", ident, ";",
-                        context(optional(and(importList, ";")), Context.ModuleImport),
-                        declarationSequence,
-                        optional(and("BEGIN", statementSequence)),
-                        required("END", "END expected (MODULE)"), ident, point),
-                     Context.ModuleDeclaration);
-
-exports.declarationSequence = declarationSequence;
-exports.expression = expression;
-exports.ident = ident;
-exports.module = modul;
-exports.procedureBody = procedureBody;
-exports.procedureDeclaration = procedureDeclaration;
-exports.procedureHeading = procedureHeading;
-exports.statement = statement;
-exports.typeDeclaration = typeDeclaration;
-exports.variableDeclaration = variableDeclaration;

+ 0 - 161
snapshot/lexer.js

@@ -1,161 +0,0 @@
-"use strict";
-
-var Errors = require("errors.js");
-var Stream = require("oberon.js/Stream.js");
-
-function isDigit(c) {return c >= '0' && c <= '9';}
-
-exports.digit = function(stream, context){
-    if (Stream.eof(stream))
-        return false;
-
-    var c = Stream.getChar(stream);
-    if (!isDigit(c))
-        return false;
-    context.handleChar(c);
-    return true;
-};
-
-exports.hexDigit = function(stream, context){
-    var c = Stream.getChar(stream);
-    if (!isDigit(c) && (c < 'A' || c > 'F'))
-        return false;
-    context.handleChar(c);
-    return true;
-};
-
-exports.point = function(stream, context){
-    if (Stream.eof(stream) 
-        || Stream.getChar(stream) != '.'
-        || (!Stream.eof(stream) && Stream.peekChar(stream) == '.')) // not a diapason ".."
-        return false;
-    context.handleLiteral(".");
-    return true;
-};
-
-exports.character = function(stream, context){
-    var c = stream.getChar();
-    if (c == '"')
-        return false;
-    context.handleChar(c);
-    return true;
-};
-
-function string(stream, context){
-    if (Stream.eof(stream))
-        return false;
-
-    var c = Stream.getChar(stream);
-    if (c != '"')
-        return false;
-
-    var result = "";
-    var parsed = false;
-    Stream.read(stream, function(c){
-        if (c == '"'){
-            parsed = true;
-            return false;
-        }
-        result += c;
-        return true;
-    });
-    if (!parsed)
-        throw new Errors.Error("unexpected end of string");
-
-    Stream.next(stream, 1);
-    context.handleString(result);
-    return true;
-}
-
-function isLetter(c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');}
-
-var reservedWords
-    = ["ARRAY", "IMPORT", "THEN", "BEGIN", "IN", "TO", "BY", "IS",
-       "TRUE", "CASE", "MOD", "TYPE", "CONST", "MODULE", "UNTIL", "DIV",
-       "NIL", "VAR", "DO", "OF", "WHILE", "ELSE", "OR", "ELSIF", "POINTER",
-       "END", "PROCEDURE", "FALSE", "RECORD", "FOR", "REPEAT", "IF", "RETURN"
-      ];
-var jsReservedWords 
-    = ["break", "case", "catch", "continue", "debugger", "default", "delete",
-       "do", "else", "finally", "for", "function", "if", "in", "instanceof",
-       "new", "return", "switch", "this", "throw", "try", "typeof", "var",
-       "void", "while", "with",
-       "Math" // Math is used in generated code for some functions so it is reserved word from code generator standpoint
-       ];
-
-exports.ident = function(stream, context){
-    if (Stream.eof(stream) || !isLetter(Stream.peekChar(stream)))
-        return false;
-    
-    var savePos = Stream.pos(stream);
-    var result = "";
-    Stream.read(stream, function(c){
-        if (!isLetter(c) && !isDigit(c) /*&& c != '_'*/)
-            return false;
-        result += c;
-        return true;
-    });
-
-    if (reservedWords.indexOf(result) != -1){
-        Stream.setPos(stream, savePos);
-        return false;
-    }
-    if (jsReservedWords.indexOf(result) != -1)
-        result += "$";
-
-    context.setIdent(result);
-    return true;
-};
-
-function skipComment(stream){
-    if (Stream.peekStr(stream, 2) != "(*")
-        return false;
-
-    Stream.next(stream, 2);
-    while (Stream.peekStr(stream, 2) != "*)"){
-        if (Stream.eof(stream))
-            throw new Errors.Error("comment was not closed");
-        if (!skipComment(stream))
-            Stream.next(stream, 1);
-        }
-    Stream.next(stream, 2);
-    return true;
-}
-
-function readSpaces(c){return ' \t\n\r'.indexOf(c) != -1;}
-
-exports.skipSpaces = function(stream, context){
-    if (context && context.isLexem && context.isLexem())
-        return;
-
-    do {
-        Stream.read(stream, readSpaces);
-    }
-    while (skipComment(stream));
-};
-
-exports.separator = function(stream, context){
-    return Stream.eof(stream) || !isLetter(Stream.peekChar(stream));
-};
-
-exports.literal = function(s){
-    return function(stream, context){
-        if (Stream.peekStr(stream, s.length) != s)
-            return false;
-        Stream.next(stream, s.length);
-        
-        if ((!context.isLexem || !context.isLexem())
-            && isLetter(s[s.length - 1])
-            && !Stream.eof(stream)
-           ){
-            var next = Stream.peekChar(stream);
-            if (isLetter(next) || isDigit(next))
-                return false;
-        }
-        
-        var result = context.handleLiteral(s);
-        return result === undefined || result;
-    };
-};
-
-exports.string = string;

+ 0 - 93
snapshot/module.js

@@ -1,93 +0,0 @@
-"use strict";
-
-var Code = require("code.js");
-var Errors = require("errors.js");
-var Procedure = require("procedure.js");
-var Symbol = require("symbol.js");
-var Type = require("type.js");
-
-var AnyTypeProc = Type.Procedure.extend({
-    init: function AnyTypeProc(){
-        Type.Procedure.prototype.init.call("PROCEDURE: JS.var");
-    },
-    result: function(){return any;}
-});
-
-var anyProc = new AnyTypeProc();
-
-var AnyType = Type.Basic.extend({
-    init: function AnyType(){
-        Type.Basic.prototype.init.call(this, "JS.var");
-    },
-    findSymbol: function(){return this;},
-    callGenerator: function(context, id){
-        return new Procedure.CallGenerator(context, id, anyProc);
-    }
-});
-
-var any = new AnyType();
-
-var doProcId = "do$";
-var varTypeId = "var$";
-
-var doProcSymbol = (function(){
-    var description = "JS predefined procedure 'do'";
-
-    var DoProcCallGenerator = Procedure.CallGenerator.extend({
-        init: function DoProcCallGenerator(context, id, type){
-            Procedure.CallGenerator.prototype.init.call(this, context, id, type);
-            this.__code = undefined;
-        },
-        prolog: function(id){return "";},
-        checkArgument: function(pos, e){
-            var type = e.type();
-            if (!(type instanceof Type.String))
-                throw new Errors.Error(
-                    "string is expected as an argument of " + description
-                    + ", got " + type.description());
-            
-            this.__code = type.value();
-            return Procedure.CallGenerator.prototype.checkArgument.call(this, pos, e);
-        },
-        epilog: function(){return "";},
-        writeArgumentCode: function(){},
-        callExpression: function(){
-            return new Code.Expression(this.__code);
-        }
-    });
-
-    var args = [new Procedure.Arg(undefined, false)];
-    var ProcType = Type.Procedure.extend({
-        init: function(){
-            Type.Procedure.prototype.init.call(this, doProcId);
-        },
-        description: function(){return description;},
-        args: function(){return args;},
-        result: function(){return undefined;},
-        callGenerator: function(context, id){
-            return new DoProcCallGenerator(context, id, this);
-        }
-        });
-
-    return new Symbol.Symbol(doProcId, new ProcType());
-})();
-
-var varTypeSymbol = function(){
-    return new Symbol.Symbol(varTypeId, new Type.TypeId(any));
-}();
-
-var JSModule = Type.Module.extend({
-    init: function Module$JSModule(){
-        Type.Module.prototype.init.call(this);
-    },
-    name: function(){return "this";},
-    findSymbol: function(id){
-        return new Symbol.Found(
-            id == doProcId ? doProcSymbol
-          : id == varTypeId ? varTypeSymbol
-          : new Symbol.Symbol(id, any));
-    }
-});
-
-exports.AnyType = AnyType;
-exports.JS = JSModule;

+ 0 - 96
snapshot/nodejs.js

@@ -1,96 +0,0 @@
-"use strict";
-
-var Rtl = require("rtl.js");
-var Code = require("code.js");
-var Context = require("context.js");
-var oc = require("oc.js");
-
-var fs = require("fs");
-var path = require("path");
-
-var ModuleGenerator = Rtl.Class.extend({
-    init: function Nodejs$ModuleGenerator(name, imports){
-        this.__name = name;
-        this.__imports = imports;
-    },
-    prolog: function(){
-        var result = "";            
-        var modules = this.__imports;
-        for(var name in modules){
-            var alias = modules[name];
-            result += "var " + alias + " = " + (name == "this" 
-                ? "GLOBAL"
-                : "require(\"" + name + ".js\")") + ";\n";
-        }
-        return result;
-    },
-    epilog: function(exports){
-        var result = "";
-        for(var access in exports){
-            var e = exports[access];
-            var code = Code.genExport(e);
-            if (code){
-                result += "exports." + e.id() + " = " + code + ";\n";
-            }
-        }
-        return result;
-    }
-});
-
-var RtlCodeUsingWatcher = Rtl.Code.extend({
-    init: function(){
-        Rtl.Code.prototype.init.call(this);
-        this.__used = false;
-    },
-    get: function(func){
-        this.__used = true;
-        return Rtl.Code.prototype.get.call(this, func);
-    },
-    used: function(){return this.__used;},
-    reset: function(){this.__used = false;}
-});
-
-function writeCompiledModule(name, code, outDir){
-    var filePath = path.join(outDir, name + ".js");
-    fs.writeFileSync(filePath, code);
-    }
-
-function compile(sources, handleErrors, outDir){
-    var rtlCodeWatcher = new RtlCodeUsingWatcher();
-    var rtl = new Rtl.RTL(rtlCodeWatcher);
-    var moduleCode = function(name, imports){return new ModuleGenerator(name, imports);};
-
-    var compiledFilesStack = [];
-    oc.compileModules(
-            sources,
-            function(name){
-                var fileName = name;
-                if (!path.extname(fileName).length)
-                    fileName += ".ob";
-                compiledFilesStack.push(fileName);
-                return fs.readFileSync(fileName, "utf8");
-            },
-            function(moduleResolver){return new Context.Context(
-                new Code.Generator(),
-                moduleCode,
-                rtl,
-                moduleResolver);},
-            function(e){handleErrors("File \"" + compiledFilesStack[compiledFilesStack.length - 1] + "\", " + e);},
-            function(name, code){
-                if (rtlCodeWatcher.used()){
-                    code = "var " + rtl.name() + " = require(\"" + rtl.name() 
-                         + ".js\")." + rtl.name() + ";\n" + code;
-                    rtlCodeWatcher.reset();
-                }
-                writeCompiledModule(name, code, outDir);
-                compiledFilesStack.pop();
-            });
-
-    var rtlCode = rtl.generate();
-    if (rtlCode){
-        rtlCode += "\nexports." + rtl.name() + " = " + rtl.name() + ";";
-        writeCompiledModule(rtl.name(), rtlCode, outDir);
-    }
-}
-
-exports.compile = compile;

+ 0 - 42
snapshot/oberon.js/JsString.js

@@ -1,42 +0,0 @@
-var RTL$ = require("RTL$.js").RTL$;
-var JS = GLOBAL;
-var Type = RTL$.extend({
-	init: function Type(){
-	}
-});
-
-function len(self/*Type*/){
-	var result = 0;
-	result = self.length;
-	return result;
-}
-
-function at(self/*Type*/, pos/*INTEGER*/){
-	var result = 0;
-	result = self[pos];
-	return result;
-}
-
-function indexOf(self/*Type*/, c/*CHAR*/){
-	var result = 0;
-	result = self.indexOf(JS.String.fromCharCode(c));
-	return result;
-}
-
-function indexOfFrom(self/*Type*/, c/*CHAR*/, pos/*INTEGER*/){
-	var result = 0;
-	result = self.indexOf(JS.String.fromCharCode(c), pos);
-	return result;
-}
-
-function substr(self/*Type*/, pos/*INTEGER*/, len/*INTEGER*/){
-	var result = null;
-	result = self.substr(pos, len);
-	return result;
-}
-exports.Type = Type;
-exports.len = len;
-exports.at = at;
-exports.indexOf = indexOf;
-exports.indexOfFrom = indexOfFrom;
-exports.substr = substr;

+ 0 - 23
snapshot/oberon.js/RTL$.js

@@ -1,23 +0,0 @@
-var RTL$ = {
-    extend: function extend(methods){
-        function Type(){
-            for(var m in methods)
-                this[m] = methods[m];
-        }
-        Type.prototype = this.prototype;
-
-        var result = methods.init;
-        result.prototype = new Type(); // inherit this.prototype
-        result.prototype.constructor = result; // to see constructor name in diagnostic
-        
-        result.extend = extend;
-        return result;
-    },
-    assert: function (condition, code){
-        if (!condition)
-            throw new Error("assertion failed"
-                          + ((code !== undefined) ? " with code " + code : ""));
-    }
-};
-
-exports.RTL$ = RTL$;

+ 0 - 87
snapshot/oberon.js/Stream.js

@@ -1,87 +0,0 @@
-var RTL$ = require("RTL$.js").RTL$;
-var JsString = require("JsString.js");
-var Type = RTL$.extend({
-	init: function Type(){
-		this.s = null;
-		this.pos = 0;
-	}
-});
-
-function make(text/*Type*/){
-	var result = null;
-	result = new Type();
-	result.s = text;
-	return result;
-}
-
-function eof(self/*Type*/){
-	return self.pos == JsString.len(self.s);
-}
-
-function pos(self/*Type*/){
-	return self.pos;
-}
-
-function setPos(self/*Type*/, pos/*INTEGER*/){
-	RTL$.assert(pos <= JsString.len(self.s));
-	self.pos = pos;
-}
-
-function next(self/*Type*/, n/*INTEGER*/){
-	RTL$.assert((self.pos + n | 0) <= JsString.len(self.s));
-	self.pos = self.pos + n | 0;
-}
-
-function peekChar(self/*Type*/){
-	RTL$.assert(!eof(self));
-	return JsString.at(self.s, self.pos);
-}
-
-function getChar(self/*Type*/){
-	var result = 0;
-	RTL$.assert(!eof(self));
-	result = JsString.at(self.s, self.pos);
-	++self.pos;
-	return result;
-}
-
-function peekStr(self/*Type*/, len/*INTEGER*/){
-	var max = 0;
-	max = JsString.len(self.s) - self.pos | 0;
-	if (len > max){
-		len = max;
-	}
-	return JsString.substr(self.s, self.pos, len);
-}
-
-function read(self/*Type*/, f/*ReaderProc*/){
-	while (true){
-		if (!eof(self) && f(peekChar(self))){
-			next(self, 1);
-		} else break;
-	}
-	return !eof(self);
-}
-
-function lineNumber(self/*Type*/){
-	var line = 0;
-	var lastPos = 0;
-	lastPos = JsString.indexOf(self.s, 13);
-	while (true){
-		if (lastPos != -1 && lastPos < self.pos){
-			++line;
-			lastPos = JsString.indexOfFrom(self.s, 13, lastPos + 1 | 0);
-		} else break;
-	}
-	return line + 1 | 0;
-}
-exports.make = make;
-exports.eof = eof;
-exports.pos = pos;
-exports.setPos = setPos;
-exports.next = next;
-exports.peekChar = peekChar;
-exports.getChar = getChar;
-exports.peekStr = peekStr;
-exports.read = read;
-exports.lineNumber = lineNumber;

+ 0 - 132
snapshot/oc.js

@@ -1,132 +0,0 @@
-"use strict";
-
-var Code = require("code.js");
-var Context = require("context.js");
-var Errors = require("errors.js");
-var Grammar = require("grammar.js");
-var Lexer = require("lexer.js");
-var ImportRTL = require("rtl.js");
-var Stream = require("oberon.js/Stream.js");
-
-var RTL = ImportRTL.RTL;
-var Class = ImportRTL.Class;
-
-var CompiledModule = Class.extend({
-    init: function CompiledModule(symbol, code, exports){
-        this.__symbol = symbol;
-        this.__code = code;
-        this.__exports = exports;
-    },
-    symbol: function(){return this.__symbol;},
-    code: function(){return this.__code;},
-    exports: function(){return this.__exports;}
-});
-
-function compileModule(stream, context, handleErrors){
-    Lexer.skipSpaces(stream, context);  
-    try {
-        if (!Grammar.module(stream, context))
-            throw new Errors.Error("syntax error");
-    }
-    catch (x) {
-        if (x instanceof Errors.Error) {
-            //console.log(context.getResult());
-            if (handleErrors){
-                handleErrors("line " + Stream.lineNumber(stream) + ": " + x);
-                return undefined;
-            }
-        }
-        throw x;
-    }
-    var scope = context.currentScope();
-    return new CompiledModule(
-            scope.module(),
-            context.codeGenerator().getResult(),
-            scope.exports());
-}
-
-function compileModulesFromText(
-        text,
-        contextFactory,
-        resolveModule,
-        handleCompiledModule,
-        handleErrors){
-    var stream = Stream.make(text);
-    do {
-        var context = contextFactory(resolveModule);
-        var module = compileModule(stream, context, handleErrors);
-        if (!module)
-            return;
-        handleCompiledModule(module);
-        Lexer.skipSpaces(stream);
-    }
-    while (!Stream.eof(stream));
-}
-
-var ModuleResolver = Class.extend({
-    init: function Oc$ModuleResolver(compile, handleCompiledModule, moduleReader){
-        this.__modules = {};
-        this.__compile = compile;
-        this.__moduleReader = moduleReader;
-        this.__handleCompiledModule = handleCompiledModule;
-    },
-    compile: function(text){
-        this.__compile(text, this.__resolveModule.bind(this), this.__handleModule.bind(this));
-    },
-    __resolveModule: function(name){
-        if (this.__moduleReader && !this.__modules[name])
-            this.compile(this.__moduleReader(name));
-        return this.__modules[name];
-    },
-    __handleModule: function(module){
-        var symbol = module.symbol();
-        var moduleName = symbol.id();
-        this.__modules[moduleName] = symbol.info();
-        this.__handleCompiledModule(moduleName, module.code());
-    }
-});
-
-function makeResolver(contextFactory, handleCompiledModule, handleErrors, moduleReader){
-    return new ModuleResolver(
-        function(text, resolveModule, handleModule){
-            compileModulesFromText(text,
-                                   contextFactory,
-                                   resolveModule,
-                                   handleModule,
-                                   handleErrors);
-        },
-        handleCompiledModule,
-        moduleReader
-        );
-}
-
-function compileModules(names, moduleReader, contextFactory, handleErrors, handleCompiledModule){
-    var resolver = makeResolver(contextFactory, handleCompiledModule, handleErrors, moduleReader);
-    names.forEach(function(name){ resolver.compile(moduleReader(name)); });
-}
-
-function compile(text, handleErrors){
-    var result = "";
-    var rtl = new RTL();
-    var moduleCode = function(name, imports){return new Code.ModuleGenerator(name, imports);};
-    var resolver = makeResolver(
-            function(moduleResolver){
-                return new Context.Context(new Code.Generator(),
-                                           moduleCode,
-                                           rtl,
-                                           moduleResolver);
-            },
-            function(name, code){result += code;},
-            handleErrors
-            );
-    resolver.compile(text);
-
-    var rtlCode = rtl.generate();
-    if (rtlCode)
-        result = rtlCode + result;
-    return result;
-}
-
-exports.compileModule = compileModule;
-exports.compile = compile;
-exports.compileModules = compileModules;

+ 0 - 24
snapshot/oc_nodejs.js

@@ -1,24 +0,0 @@
-"use strict";
-
-var nodejs = require("nodejs.js");
-
-function main(){
-    if (process.argv.length <= 3){
-        console.info("Usage: <oc_nodejs> <output dir> <input oberon module file(s)>");
-        return -1;
-    }
-
-    var outDir = process.argv[2];
-    var sources = process.argv.slice(3);
-    var errors = "";
-    nodejs.compile(sources, function(e){errors += e;}, outDir);
-    if (errors.length){
-        console.error(errors);
-        return -2;
-    }
-
-    console.info("OK!");
-    return 0;
-}
-
-process.exit(main());

+ 0 - 179
snapshot/operator.js

@@ -1,179 +0,0 @@
-"use strict";
-
-var Cast = require("cast.js");
-var Code = require("code.js");
-var Errors = require("errors.js");
-var Type = require("type.js");
-
-var precedence = {
-    unary: 4,
-    mulDivMod: 5,
-    addSub: 6,
-    shift: 7,
-    relational: 8,
-    equal: 9,
-    bitAnd: 10,
-    bitXor: 11,
-    bitOr: 12,
-    and: 13,
-    or: 14,
-    conditional: 15,
-    assignment: 17
-};
-
-function makeBinary(op, code, precedence, resultPrecedence){
-    return function(left, right, context){
-        var leftValue = left.constValue();
-        var rightValue = right.constValue();
-        var value = (leftValue !== undefined && rightValue !== undefined)
-            ? op(leftValue, rightValue) : undefined;
-
-        var leftCode = Code.adjustPrecedence(left.deref(), precedence);
-
-        // right code needs parentheses even if it has the same percedence
-        var rightCode = Code.adjustPrecedence(right.deref(), precedence - 1);
-        var expCode = (typeof code == "function")
-                    ? code(leftCode, rightCode, context)
-                    : leftCode + code + rightCode;
-        return new Code.Expression(expCode, left.type(), undefined, value, resultPrecedence ? resultPrecedence : precedence);
-    };
-}
-
-function makeUnary(op, code){
-    return function(e){
-        var type = e.type();
-        var value = e.constValue();
-        if (value !== undefined)
-            value = op(value, type) ;
-        var expCode = code + Code.adjustPrecedence(e.deref(), precedence.unary);
-        return new Code.Expression(expCode, type, undefined, value);
-    };
-}
-
-var mul = makeBinary(function(x, y){return x * y;}, " * ", precedence.mulDivMod);
-var div = makeBinary(function(x, y){return x / y;}, " / ", precedence.mulDivMod);
-
-function pow2(e){
-    return new Code.Expression("Math.pow(2, " + e.deref().code() + ")",
-                               Type.basic.real);
-}
-
-function log2(e){
-    return new Code.Expression("(Math.log(" + e.deref().code() + ") / Math.LN2) | 0",
-                               Type.basic.integer, undefined, undefined, precedence.bitOr);
-}
-
-function assign(left, right, context){
-    var info = left.designator().info();
-    if (!(info instanceof Type.Variable) || info.isReadOnly())
-        throw new Errors.Error("cannot assign to " + info.idType());
-
-    var leftCode = left.code();
-    var leftType = left.type();
-    var rightCode = right.code();
-    var rightType = right.type();
-
-    var isArray = leftType instanceof Type.Array;
-    if (isArray
-        && leftType.elementsType() == Type.basic.ch
-        && rightType instanceof Type.String){
-        if (leftType.length() === undefined)
-            throw new Errors.Error("string cannot be assigned to open " + leftType.description());
-        if (rightType.length() > leftType.length())
-            throw new Errors.Error(
-                leftType.length() + "-character ARRAY is too small for "
-                + rightType.length() + "-character string");
-        return context.rtl().assignArrayFromString(leftCode, rightCode);
-    }
-
-    var castOperation = Cast.implicit(rightType, leftType);
-    if (!castOperation)
-        throw new Errors.Error("type mismatch: '" + leftCode
-                             + "' is '" + leftType.description()
-                             + "' and cannot be assigned to '" + rightType.description() + "' expression");
-
-    if (isArray && rightType instanceof Type.Array){
-        if (leftType.length() === undefined)
-            throw new Errors.Error("'" + leftCode
-                                 + "' is open '" + leftType.description()
-                                 + "' and cannot be assigned");
-    }
-    
-    if (isArray || rightType instanceof Type.Record)
-        return context.rtl().copy(rightCode, leftCode);
-
-    var castCode = castOperation(context, right.deref()).code();
-    rightCode = castCode ? castCode : rightCode;
-    return leftCode + (info instanceof Type.VariableRef 
-                      ? ".set(" + rightCode + ")"
-                      : " = " + rightCode);
-}
-
-function makeInplace(code, altOp){
-    return function(left, right){
-        var info = left.designator().info();
-        if (info instanceof Type.VariableRef)
-            return assign(left, altOp(left, right));
-        return left.code() + code + right.deref().code();
-    };
-}
-
-function makeBinaryInt(op, code, prec){
-    return makeBinary(
-            function(x, y){return op(x, y) | 0;},
-            function(x, y){return x + code + y + " | 0";},
-            prec,
-            precedence.bitOr);
-}
-
-var operators = {
-    add:    makeBinary(   function(x, y){return x + y;}, " + ", precedence.addSub),
-    addInt: makeBinaryInt(function(x, y){return x + y;}, " + ", precedence.addSub),
-    sub:    makeBinary(   function(x, y){return x - y;}, " - ", precedence.addSub),
-    subInt: makeBinaryInt(function(x, y){return x - y;}, " - ", precedence.addSub),
-    mul:    mul,
-    mulInt: makeBinaryInt(function(x, y){return x * y;}, " * ", precedence.mulDivMod),
-    div:    div,
-    divInt: makeBinaryInt(function(x, y){return x / y;}, " / ", precedence.mulDivMod),
-    mod:        makeBinary(function(x, y){return x % y;}, " % ", precedence.mulDivMod),
-    setUnion:   makeBinary(function(x, y){return x | y;}, " | ", precedence.bitOr),
-    setDiff:    makeBinary(function(x, y){return x & ~y;}, " & ~", precedence.bitAnd),
-    setIntersection: makeBinary(function(x, y){return x & y;}, " & ", precedence.bitAnd),
-    setSymmetricDiff: makeBinary(function(x, y){return x ^ y;}, " ^ ", precedence.bitXor),
-    setInclL:   makeBinary(
-            function(x, y){return (x & y) == x;},
-            function(x, y, context){return context.rtl().setInclL(x, y);}),
-    setInclR:   makeBinary(
-            function(x, y){return (x & y) == y;},
-            function(x, y, context){return context.rtl().setInclR(x, y);}),
-
-    or:         makeBinary(function(x, y){return x || y;}, " || ", precedence.or),
-    and:        makeBinary(function(x, y){return x && y;}, " && ", precedence.and),
-
-    equal:      makeBinary(function(x, y){return x == y;}, " == ", precedence.equal),
-    notEqual:   makeBinary(function(x, y){return x != y;}, " != ", precedence.equal),
-    less:       makeBinary(function(x, y){return x < y;}, " < ", precedence.relational),
-    greater:    makeBinary(function(x, y){return x > y;}, " > ", precedence.relational),
-    eqLess:     makeBinary(function(x, y){return x <= y;}, " <= ", precedence.relational),
-    eqGreater:  makeBinary(function(x, y){return x >= y;}, " >= ", precedence.relational),
-
-    not:        makeUnary(function(x){return !x;}, "!"),
-    negate:     makeUnary(function(x){return -x;}, "-"),
-    unaryPlus:  makeUnary(function(x){return x;}, ""),
-    setComplement: makeUnary(function(x){return ~x;}, "~"),
-
-    lsl:        makeBinary(function(x, y){return x << y;}, " << ", precedence.shift),
-    asr:        makeBinary(function(x, y){return x >> y;}, " >> ", precedence.shift),
-    ror:        makeBinary(function(x, y){return x >>> y;}, " >>> ", precedence.shift),
-
-    assign:     assign,
-    mulInplace: makeInplace(" *= ", mul),
-    divInplace: makeInplace(" /= ", div),
-    
-    pow2:       pow2,
-    log2:       log2
-};
-
-for(var p in operators)
-    exports[p] = operators[p];
-exports.precedence = precedence;

+ 0 - 109
snapshot/parser.js

@@ -1,109 +0,0 @@
-"use strict";
-
-var assert = require("assert.js").ok;
-var Errors = require("errors.js");
-var Lexer = require("lexer.js");
-var Stream = require("oberon.js/Stream.js");
-
-function implicitParser(p){
-	return typeof p === "string" ? Lexer.literal(p) : p;
-}
-
-function argumentsToParsers(args){
-	var parsers = Array.prototype.slice.call(args);
-	for(var i = 0; i < parsers.length; ++i)
-		parsers[i] = implicitParser(parsers[i]);
-	return parsers;
-}
-
-exports.and = function(/*...*/){
-	assert(arguments.length >= 2);
-	var parsers = argumentsToParsers(arguments);
-
-	return function(stream, context){
-		for(var i = 0; i < parsers.length; ++i){
-			if (i)
-				Lexer.skipSpaces(stream, context);
-			
-			var p = parsers[i];
-			if (!p(stream, context))
-				return false;
-		}
-		return true;
-	};
-};
-
-exports.or = function(/*...*/){
-	assert(arguments.length >= 2);
-	var parsers = argumentsToParsers(arguments);
-
-	return function(stream, context){
-		for(var i = 0; i < parsers.length; ++i){
-			var p = parsers[i];
-			var savePos = Stream.pos(stream);
-			if (p(stream, context))
-				return true;
-			Stream.setPos(stream, savePos);
-		}
-		return false;
-	};
-};
-
-exports.repeat = function(p){
-	return function(stream, context){
-			var savePos = Stream.pos(stream);
-			while (!Stream.eof(stream) && p(stream, context)){
-				Lexer.skipSpaces(stream, context);
-				savePos = Stream.pos(stream);
-			}
-			Stream.setPos(stream, savePos);
-			return true;
-		};
-};
-
-exports.optional = function(parser){
-	assert(arguments.length == 1);
-	var p = implicitParser(parser);
-
-	return function(stream, context){
-		var savePos = Stream.pos(stream);
-		if ( !p(stream, context))
-			Stream.setPos(stream, savePos);
-		return true;
-		};
-};
-
-exports.required = function(parserOrString, error){
-	var parser = implicitParser(parserOrString);
-	
-	return function(stream, context){
-		if (!parser(stream, context))
-			throw new Errors.Error(error 
-					? error 
-					: ("'" + parserOrString + "' expected"));
-		return true;
-	};
-};
-
-exports.context = function(parser, ContextFactory){
-	return function(stream, child){
-		var context = new ContextFactory(child);
-		if (!parser(stream, context))
-			return false;
-		if (context.endParse)
-			return context.endParse() !== false;
-		return true;
-	};
-};
-
-exports.emit = function(parser, action){
-	assert(action);
-	var p = implicitParser(parser);
-
-	return function(stream, context){
-		if (!p(stream, context))
-			return false;
-		action(context);
-		return true;
-	};
-};

+ 0 - 617
snapshot/procedure.js

@@ -1,617 +0,0 @@
-"use strict";
-
-var Cast = require("cast.js");
-var Class = require("rtl.js").Class;
-var Code = require("code.js");
-var Errors = require("errors.js");
-var op = require("operator.js");
-var precedence = require("operator.js").precedence;
-var Symbol = require("symbol.js");
-var Type = require("type.js");
-
-var Arg = Class.extend({
-    init: function(type, isVar){
-        this.type = type;
-        this.isVar = isVar;
-    },
-    description: function(){
-        return (this.isVar ? "VAR " : "") + this.type.description();
-    }
-});
-exports.Arg = Arg;
-
-var CheckArgumentResult = Arg.extend({
-    init: function(type, isVar, convert){
-        Arg.prototype.init.call(this, type, isVar);
-        this.convert = convert;
-    }
-});
-
-var ProcCallGenerator = Class.extend({
-    init: function ProcCallGenerator(context, id, type){
-        this.__context = context;
-        this.__id = id;
-        this.__type = type;
-        this.__argumentsCount = 0;
-        this.__code = new Code.SimpleGenerator();
-        this.writeCode(this.prolog());
-    },
-    //id: function(){return this.__id;},
-    context: function(){return this.__context;},
-    handleArgument: function(e){
-        var pos = this.__argumentsCount++;
-        var isVarArg = false;
-        var convert;
-        if (this.__type.args){
-            var expectedArguments = this.__type.args();
-            if (pos >= expectedArguments.length )
-                // ignore, handle error after parsing all arguments
-                return;
-            
-            var arg = this.checkArgument(pos, e);
-            isVarArg = arg.isVar;
-            convert = arg.convert;
-        }
-        this.writeArgumentCode(e, pos, isVarArg, convert);
-    },
-    writeArgumentCode: function(e, pos, isVar, convert){
-        e = isVar ? e.ref() : e.deref();
-        var code = (convert ? convert(this.__context, e) : e).code();
-        var prefix = pos ? ", " : "";
-        this.writeCode(prefix + code);
-    },
-    end: function(){
-        if (this.__type.args)
-            this.checkArgumentsCount(this.__argumentsCount);
-        return this.callExpression();
-    },
-    callExpression: function(){
-        this.writeCode(this.epilog());
-        return new Code.Expression(this.__code.result(),
-                                   this.resultType());
-    },
-    resultType: function(){return this.__type ? this.__type.result() : undefined;},
-    prolog: function(){return this.__id + "(";},
-    checkArgumentsCount: function(count){
-        var procArgs = this.__type.args();
-        if (count != procArgs.length)
-            throw new Errors.Error(procArgs.length + " argument(s) expected, got "
-                                 + this.__argumentsCount);
-    },
-    checkArgument: function(pos, e){
-        var arg = this.__type.args()[pos];
-        var castOperation;
-        var expectType = arg.type; // can be undefined for predefined functions (like NEW), dont check it in this case
-        if (expectType){
-            var type = e.type();
-            castOperation = Cast.implicit(type, expectType);
-            if (!castOperation)
-                throw new Errors.Error("type mismatch for argument " + (pos + 1) + ": '" + type.description()
-                                     + "' cannot be converted to '" + expectType.description() + "'");
-        }
-        if (arg.isVar){
-            var designator = e.designator();
-            if (!designator)
-                throw new Errors.Error("expression cannot be used as VAR parameter");
-            var info = designator.info();
-            if (info instanceof Type.Const)
-                throw new Errors.Error("constant cannot be used as VAR parameter");
-            if (info.isReadOnly())
-                throw new Errors.Error(info.idType() + " cannot be used as VAR parameter");
-        }
-        return new CheckArgumentResult(arg.type, arg.isVar, castOperation);
-    },
-    epilog: function(){return ")";},
-    writeCode: function(s){this.__code.write(s);}
-});
-
-var DefinedProc = Type.Procedure.extend({
-    init: function DefinedProc(name){
-        Type.Procedure.prototype.init.call(this, name);
-        this.__arguments = undefined;
-        this.__result = undefined;
-    },
-    define: function(args, result){
-        this.__arguments = args;
-        this.__result = result;
-    },
-    args: function(){return this.__arguments;},
-    result: function(){return this.__result;},
-    description: function(){
-        var name = this.name();
-        if (name)
-            return name;
-        return 'PROCEDURE' + this.__dumpProcArgs()
-            + (this.__result ? ": " + this.__result.name() : "");
-        },
-    callGenerator: function(context, id){
-        return new ProcCallGenerator(context, id, this);
-    },
-    __dumpProcArgs: function(){
-        if (!this.__arguments.length)
-            return this.__result ? "()" : "";
-        
-        var result = "(";
-        for(var i = 0; i < this.__arguments.length; ++i){
-            if (i)
-                result += ", ";
-            result += this.__arguments[i].description();
-        }
-        result += ")";
-        return result;
-    }
-});
-
-var Std = Type.Procedure.extend({
-    init: function Std(name, args, result, callGeneratorFactory){
-        Type.Procedure.prototype.init.call(this, name);
-        this.__arguments = args;
-        this.__result = result;
-        this.__callGeneratorFactory = callGeneratorFactory;
-    },
-    description: function(){return "standard procedure " + this.name();},
-    args: function(){return this.__arguments;},
-    result: function(){return this.__result;},
-    callGenerator: function(context, id){
-        return this.__callGeneratorFactory(context, id, this);
-    }
-});
-
-var ExpCallGenerator = ProcCallGenerator.extend({
-    init: function ExpCallGenerator(context, id, type){
-        ProcCallGenerator.prototype.init.call(this, context, id, type);
-        this.__args = [];
-    },
-    prolog: function(){return "";},
-    epilog: function(){return "";},
-    writeArgumentCode: function(){},
-    checkArgument: function(pos, e){
-        this.__args.push(e);
-        return ProcCallGenerator.prototype.checkArgument.call(this, pos, e);
-    },
-    args: function(){return this.__args;}
-});
-
-var TwoArgToOperatorProcCallGenerator = ExpCallGenerator.extend({
-    init: function TwoArgToOperatorProcCallGenerator(context, id, type, operator){
-        ExpCallGenerator.prototype.init.call(this, context, id, type);
-        this.__operator = operator;
-    },
-    callExpression: function(){
-        var args = this.args();
-        return new Code.Expression(this.__operator(args[0], args[1]));
-    }
-});
-
-function setBitImpl(name, op){
-    var args = [new Arg(Type.basic.set, true),
-                new Arg(Type.basic.integer, false)];
-    function operator(x, y){
-        var value = y.constValue();
-        if (value === undefined || value < 0 || value > 31)
-            throw new Errors.Error("constant (0..31) expected as second argument of " + name);
-        var comment = "bit: " + (y.isTerm() ? value : Code.adjustPrecedence(y, precedence.shift));
-        value = 1 << value;
-        var valueCode = value + "/*" + comment + "*/";
-        return op(Code.adjustPrecedence(x, precedence.assignment), valueCode);
-    }
-    var proc = new Std(
-        name,
-        args,
-        undefined,
-        function(context, id, type){
-            return new TwoArgToOperatorProcCallGenerator(
-                context, id, type, operator);
-            });
-    var symbol = new Symbol.Symbol(name, proc);
-    return symbol;
-}
-
-function incImpl(name, unary, op){
-    var args = [new Arg(Type.basic.integer, true),
-                new Arg(Type.basic.integer, false)];
-    function operator(x, y){
-        if (!y)
-            return unary + x.code();
-
-        var value = y.constValue();
-        if (value === undefined)
-            throw new Errors.Error("constant expected as second argument of " + name);
-        var comment = y.isTerm() ? "" : "/*" + y.code() + "*/";
-        var valueCode = value + comment;
-        return op(x.code(), valueCode);
-    }
-    var CallGenerator = TwoArgToOperatorProcCallGenerator.extend({
-        init: function IncDecProcCallGenerator(context, id, type, operator){
-            TwoArgToOperatorProcCallGenerator.prototype.init.call(this, context, id, type, operator);
-        },
-        checkArgumentsCount: function(count){
-            checkVariableArgumentsCount(1, 2, count);
-        }
-    });
-    var proc = new Std(
-        name,
-        args,
-        undefined,
-        function(context, id, type){
-            return new CallGenerator(
-                context, id, type, operator);
-            });
-    var symbol = new Symbol.Symbol(name, proc);
-    return symbol;
-}
-
-function bitShiftImpl(name, op){
-    var CallGenerator = ExpCallGenerator.extend({
-        init: function ShiftProcCallGenerator(context, id, type){
-            ExpCallGenerator.prototype.init.call(this, context, id, type);
-        },
-        callExpression: function(){
-            var args = this.args();
-            return op(args[0], args[1]);
-        }
-    });
-    var args = [new Arg(Type.basic.integer, false),
-                new Arg(Type.basic.integer, false)
-               ];
-    var proc = new Std(
-        name,
-        args,
-        Type.basic.integer,
-        function(context, id, type){
-            return new CallGenerator(context, id, type);
-        });
-    var symbol = new Symbol.Symbol(name, proc);
-    return symbol;
-}
-
-function longShort(name){
-    var CallGenerator = ExpCallGenerator.extend({
-        init: function LongShortCallGenerator(context, id, type){
-            ExpCallGenerator.prototype.init.call(this, context, id, type);
-        },
-        callExpression: function(){return this.args()[0];}
-    });
-    var args = [new Arg(Type.basic.real, false)];
-    var proc = new Std(
-        name,
-        args,
-        Type.basic.real,
-        function(context, id, type){
-            return new CallGenerator(context, id, type);
-        });
-    var symbol = new Symbol.Symbol(name, proc);
-    return symbol;
-}
-
-function checkVariableArgumentsCount(min, max, actual){
-    if (actual < min)
-        throw new Errors.Error("at least " + min + " argument expected, got " + actual);
-    if (actual > max )
-        throw new Errors.Error("at most " + max + " arguments expected, got " + actual);
-}
-
-exports.predefined = [
-    function(){
-        var NewProcCallGenerator = ProcCallGenerator.extend({
-            init: function NewProcCallGenerator(context, id, type){
-                ProcCallGenerator.prototype.init.call(this, context, id, type);
-                this.__baseType = undefined;
-            },
-            prolog: function(id){return "";},
-            checkArgument: function(pos, e){
-                ProcCallGenerator.prototype.checkArgument.call(this, pos, e);
-
-                var type = e.type();
-                if (!(type instanceof Type.Pointer))
-                    throw new Errors.Error("POINTER variable expected, got '"
-                                         + type.name() + "'");
-                this.__baseType = type.baseType();
-                if (this.__baseType instanceof Type.NonExportedRecord)
-                    throw new Errors.Error("non-exported RECORD type cannot be used in NEW");
-                return new CheckArgumentResult(type, false);
-            },
-            epilog: function(){
-                return " = new " 
-                     + this.context().qualifyScope(this.__baseType.scope()) 
-                     + this.__baseType.cons()
-                     + "()";
-            }
-        });
-
-        var name = "NEW";
-        var args = [new Arg(undefined, true)];
-        var type = new Std(
-            name,
-            args,
-            undefined,
-            function(context, id, type){
-                return new NewProcCallGenerator(context, id, type);
-            });
-        var symbol = new Symbol.Symbol(name, type);
-        return symbol;
-    }(),
-    function(){
-        var LenProcCallGenerator = ProcCallGenerator.extend({
-            init: function LenProcCallGenerator(context, id, type){
-                ProcCallGenerator.prototype.init.call(this, context, id, type);
-            },
-            prolog: function(id){return "";},
-            checkArgument: function(pos, e){
-                var type = e.type();
-                if (type instanceof Type.Array || type instanceof Type.String)
-                    return new CheckArgumentResult(type, false);
-                
-                // should throw error
-                return ProcCallGenerator.prototype.checkArgument.call(this, pos, e);
-            },
-            epilog: function(){return ".length";}
-        });
-
-        var name = "LEN";
-        var args = [new Arg(new Type.Array("ARRAY OF any type"), false)];
-        var type = new Std(
-            name,
-            args,
-            Type.basic.integer,
-            function(context, id, type){
-                return new LenProcCallGenerator(context, id, type);
-            });
-        var symbol = new Symbol.Symbol(name, type);
-        return symbol;
-    }(),
-    function(){
-        var CallGenerator = ExpCallGenerator.extend({
-            init: function OddProcCallGenerator(context, id, type){
-                ExpCallGenerator.prototype.init.call(this, context, id, type);
-            },
-            callExpression: function(){
-                var e = this.args()[0];
-                var code = Code.adjustPrecedence(e, precedence.bitAnd);
-                return new Code.Expression(code + " & 1", Type.basic.bool, undefined, e.constValue(), precedence.bitAnd);
-            }
-        });
-        var name = "ODD";
-        var args = [new Arg(Type.basic.integer, false)];
-        var type = new Std(
-            "ODD",
-            args,
-            Type.basic.bool,
-            function(context, id, type){
-                return new CallGenerator(context, id, type);
-            });
-        var symbol = new Symbol.Symbol(name, type);
-        return symbol;
-    }(),
-    function(){
-        var AssertProcCallGenerator = ProcCallGenerator.extend({
-            init: function AssertProcCallGenerator(context, id, type){
-                ProcCallGenerator.prototype.init.call(this, context, id, type);
-            },
-            prolog: function(){return this.context().rtl().assertId() + "(";},
-            checkArgumentsCount: function(count){
-                checkVariableArgumentsCount(1, 2, count);
-            }
-        });
-
-        var args = [new Arg(Type.basic.bool), new Arg(Type.basic.integer)];
-        var proc = new Std(
-            "ASSERT",
-            args,
-            undefined,
-            function(context, id, type){
-                return new AssertProcCallGenerator(context, id, type);
-            });
-        var symbol = new Symbol.Symbol("ASSERT", proc);
-        return symbol;
-    }(),
-    setBitImpl("INCL", function(x, y){return x + " |= " + y;}),
-    setBitImpl("EXCL", function(x, y){return x + " &= ~(" + y + ")";}),
-    incImpl("INC", "++", function(x, y){return x + " += " + y;}),
-    incImpl("DEC", "--", function(x, y){return x + " -= " + y;}),
-    function(){
-        var CallGenerator = ProcCallGenerator.extend({
-            init: function AbsProcCallGenerator(context, id, type){
-                ProcCallGenerator.prototype.init.call(this, context, id, type);
-                this.__argType = undefined;
-            },
-            prolog: function(){return "Math.abs(";},
-            checkArgument: function(pos, e){
-                var type = e.type();
-                if (Type.numeric.indexOf(type) == -1)
-                    throw new Errors.Error("type mismatch: expected numeric type, got '" +
-                                           type.description() + "'");
-                this.__argType = type;
-                return ProcCallGenerator.prototype.checkArgument.call(this, pos, e);
-            },
-            resultType: function(){return this.__argType;}
-        });
-        var args = [new Arg(undefined, false)];
-        var proc = new Std(
-            "ABS",
-            args,
-            undefined,
-            function(context, id, type){
-                return new CallGenerator(context, id, type);
-            });
-        var symbol = new Symbol.Symbol("ABS", proc);
-        return symbol;
-    }(),
-    function(){
-        var CallGenerator = ProcCallGenerator.extend({
-            init: function FloorProcCallGenerator(context, id, type){
-                ProcCallGenerator.prototype.init.call(this, context, id, type);
-            },
-            prolog: function(){return "Math.floor(";}
-        });
-        var args = [new Arg(Type.basic.real, false)];
-        var proc = new Std(
-            "FLOOR",
-            args,
-            Type.basic.integer,
-            function(context, id, type){
-                return new CallGenerator(context, id, type);
-            });
-        var symbol = new Symbol.Symbol("FLOOR", proc);
-        return symbol;
-    }(),
-    function(){
-        var CallGenerator = ExpCallGenerator.extend({
-            init: function FltProcCallGenerator(context, id, type){
-                ExpCallGenerator.prototype.init.call(this, context, id, type);
-            },
-            callExpression: function(){
-                var e = this.args()[0];
-                return new Code.Expression(e.code(), Type.basic.real, undefined, e.constValue(), e.maxPrecedence());
-            }
-        });
-        var args = [new Arg(Type.basic.integer, false)];
-        var proc = new Std(
-            "FLT",
-            args,
-            Type.basic.real,
-            function(context, id, type){
-                return new CallGenerator(context, id, type);
-            });
-        var symbol = new Symbol.Symbol("FLT", proc);
-        return symbol;
-    }(),
-    longShort("LONG"),
-    longShort("SHORT"),
-    bitShiftImpl("LSL", op.lsl),
-    bitShiftImpl("ASR", op.asr),
-    bitShiftImpl("ROR", op.ror),
-    function(){
-        var CallGenerator = ProcCallGenerator.extend({
-            init: function OrdProcCallGenerator(context, id, type){
-                ProcCallGenerator.prototype.init.call(this, context, id, type);
-                this.__callExpression = undefined;
-            },
-            prolog: function(){return "";},
-            epilog: function(){return "";},
-            checkArgument: function(pos, e){
-                var type = e.type();
-                if (type == Type.basic.ch || type == Type.basic.set)
-                    this.__callExpression = new Code.Expression(
-                        e.code(), Type.basic.integer, undefined, e.constValue());
-                else if (type == Type.basic.bool){
-                    var code = Code.adjustPrecedence(e, precedence.conditional) + " ? 1 : 0";
-                    var value = e.constValue();
-                    if (value !== undefined)
-                        value = value ? 1 : 0;
-                    this.__callExpression = new Code.Expression(
-                        code, Type.basic.integer, undefined, value, precedence.conditional);
-                }
-                else if (type instanceof Type.String){
-                    var ch = type.asChar();
-                    if (ch !== undefined)
-                        this.__callExpression = new Code.Expression(
-                            "" + ch, Type.basic.integer);
-                }
-                
-                if (this.__callExpression)
-                    return new CheckArgumentResult(type, false);
-
-                // should throw error
-                return ProcCallGenerator.prototype.checkArgument.call(this, pos, e);
-            },
-            callExpression: function(){return this.__callExpression;}
-        });
-        var name = "ORD";
-        var argType = new Type.Basic("CHAR or BOOLEAN or SET");
-        var args = [new Arg(argType, false)];
-        var type = new Std(
-            name,
-            args,
-            Type.basic.integer,
-            function(context, id, type){
-                return new CallGenerator(context, id, type);
-            });
-        var symbol = new Symbol.Symbol(name, type);
-        return symbol;
-    }(),
-    function(){
-        var CallGenerator = ExpCallGenerator.extend({
-            init: function ChrProcCallGenerator(context, id, type){
-                ExpCallGenerator.prototype.init.call(this, context, id, type);
-            },
-            callExpression: function(){
-                return new Code.Expression(this.args()[0].code(), Type.basic.ch);
-            }
-        });
-        var name = "CHR";
-        var type = new Std(
-            name,
-            [new Arg(Type.basic.integer, false)],
-            Type.basic.ch,
-            function(context, id, type){
-                return new CallGenerator(context, id, type);
-            });
-        var symbol = new Symbol.Symbol(name, type);
-        return symbol;
-    }(),
-    function(){
-        var CallGenerator = ExpCallGenerator.extend({
-            init: function CopyProcCallGenerator(context, id, type){
-                ExpCallGenerator.prototype.init.call(this, context, id, type);
-            },
-            callExpression: function(){
-                var args = this.args();
-                return new Code.Expression(op.assign(args[1], args[0], this.context()));
-            }
-        });
-        var name = "COPY";
-        var type = new Std(
-            name,
-            [new Arg(undefined, false),
-             new Arg(new Type.Array("ARRAY OF CHAR", undefined, Type.basic.ch), true)],
-            undefined,
-            function(context, id, type){
-                return new CallGenerator(context, id, type);
-            });
-        var symbol = new Symbol.Symbol(name, type);
-        return symbol;
-    }(),
-    function(){
-        var args = [new Arg(Type.basic.real, true),
-                    new Arg(Type.basic.integer, false)];
-        function operator(x, y){
-            return op.mulInplace(x, op.pow2(y));
-        }
-        var name = "PACK";
-        var proc = new Std(
-            name,
-            args,
-            undefined,
-            function(context, id, type){
-                return new TwoArgToOperatorProcCallGenerator(
-                    context, id, type, operator);
-                });
-        var symbol = new Symbol.Symbol(name, proc);
-        return symbol;
-    }(),
-    function(){
-        var args = [new Arg(Type.basic.real, true),
-                    new Arg(Type.basic.integer, true)];
-        function operator(x, y){
-            return op.assign(y, op.log2(x)) +
-                   "; " +
-                   op.divInplace(x, op.pow2(y));
-        }
-        var name = "UNPACK";
-        var proc = new Std(
-            name,
-            args,
-            undefined,
-            function(context, id, type){
-                return new TwoArgToOperatorProcCallGenerator(
-                    context, id, type, operator);
-                });
-        var symbol = new Symbol.Symbol(name, proc);
-        return symbol;
-    }()
-    ];
-
-exports.CallGenerator = ProcCallGenerator;
-exports.Type = DefinedProc;
-exports.Std = Std;

+ 0 - 183
snapshot/rtl.js

@@ -1,183 +0,0 @@
-"use strict";
-
-// support IE8
-if (!Array.prototype.indexOf)
-    Array.prototype.indexOf = function(x){
-        for(var i = 0; i < this.length; ++i)
-            if (this[i] === x)
-                return i;
-        return -1;
-    };
-
-function Class(){}
-Class.extend = function extend(methods){
-        function Type(){
-            for(var m in methods)
-                this[m] = methods[m];
-        }
-        Type.prototype = this.prototype;
-
-        var result = methods.init;
-        result.prototype = new Type(); // inherit this.prototype
-        result.prototype.constructor = result; // to see constructor name in diagnostic
-        
-        result.extend = extend;
-        return result;
-    };
-
-var impl = {
-    extend: Class.extend,
-    typeGuard: function(from, to){
-        if (!(from instanceof to))
-            throw new Error("typeguard assertion failed");
-        return from;
-    },
-    makeArray: function(/*dimensions, initializer*/){
-        var forward = Array.prototype.slice.call(arguments);
-        var result = new Array(forward.shift());
-        var i;
-        if (forward.length == 1){
-            var init = forward[0];
-            if (typeof init == "function")
-                for(i = 0; i < result.length; ++i)
-                    result[i] = init();
-            else
-                for(i = 0; i < result.length; ++i)
-                    result[i] = init;
-        }
-        else
-            for(i = 0; i < result.length; ++i)
-                result[i] = this.makeArray.apply(this, forward);
-        return result;
-    },
-    makeSet: function(/*...*/){
-        var result = 0;
-        
-        function checkBit(b){
-            if (b < 0 || b > 31)
-                throw new Error("integers between 0 and 31 expected, got " + b);
-        }
-
-        function setBit(b){
-            checkBit(b);
-            result |= 1 << b;
-        }
-        
-        for(var i = 0; i < arguments.length; ++i){
-            var b = arguments[i];
-            if (b instanceof Array){
-                var from = b[0];
-                var to = b[1];
-                if (from < to)
-                    throw new Error("invalid SET diapason: " + from + ".." + to);
-                for(var bi = from; bi <= to; ++bi)
-                    setBit(bi);
-            }
-            else
-                setBit(b);
-        }
-        return result;
-    },
-    makeRef: function(obj, prop){
-        return {set: function(v){ obj[prop] = v; },
-                get: function(){ return obj[prop]; }};
-    },
-    setInclL: function(l, r){return (l & r) == l;},
-    setInclR: function(l, r){return (l & r) == r;},
-    assignArrayFromString: function(a, s){
-        var i;
-        for(i = 0; i < s.length; ++i)
-            a[i] = s.charCodeAt(i);
-        for(i = s.length; i < a.length; ++i)
-            a[i] = 0;
-    },
-    strToArray: function(s){
-        var result = new Array(s.length);
-        for(var i = 0; i < s.length; ++i)
-            result[i] = s.charCodeAt(i);
-        return result;
-    },
-    copy: function(from, to){
-        for(var prop in to){
-            if (to.hasOwnProperty(prop)){
-                var v = from[prop];
-                if (v !== null && typeof v == "object")
-                    this.copy(v, to[prop]);
-                else
-                    to[prop] = v;
-            }
-        }
-    },
-    assert: function(condition, code){
-        if (!condition)
-            throw new Error("assertion failed"
-                          + ((code !== undefined) ? " with code " + code : ""));
-    }
-};
-
-var Code = Class.extend({
-    init: function RTL$Code(){
-        var names = [];
-        for(var f in impl)
-            names.push(f);
-        this.__functions = names;
-    },
-    functions: function(){return this.__functions;},
-    get: function(func){return impl[func];}
-});
-
-var defaultCode = new Code();
-
-exports.Class = Class;
-exports.RTL = Class.extend({
-    init: function RTL(code){
-        this.__entries = {};
-        this.__code = code || defaultCode;        
-        var names = this.__code.functions();
-        for(var i = 0; i < names.length; ++i){
-            var name = names[i];
-            this[name] = this.__makeOnDemand(name);
-            this[name + "Id"] = this.__makeIdOnDemand(name);
-        }
-    },
-    name: function(){return "RTL$";},
-    generate: function(){
-        var result = "var " + this.name() + " = {\n";
-        var firstEntry = true;
-        for (var name in this.__entries){
-            if (!firstEntry)
-                result += ",\n";
-            else
-                firstEntry = false;
-            result += "    " + name + ": " + this.__entries[name].toString();
-        }
-        if (!firstEntry)
-            result += "\n};\n";
-        else
-            result = undefined;
-        
-        return result;
-    },
-    __makeIdOnDemand: function(name){
-        return function(){
-            if (!this.__entries[name])
-                this.__entries[name] = this.__code.get(name);
-            return this.name() + "." + name;
-        };
-    },
-    __makeOnDemand: function(name){
-        return function(){
-            var result = this[name +"Id"]() + "(";
-            if (arguments.length){
-                result += arguments[0];
-                for(var a = 1; a < arguments.length; ++a)
-                    result += ", " + arguments[a];
-            }
-            result += ")";
-            return result;
-        };
-    }
-
-});
-
-exports.Code = Code;

+ 0 - 132
snapshot/scope.js

@@ -1,132 +0,0 @@
-"use strict";
-
-var Class = require("rtl.js").Class;
-var Errors = require("errors.js");
-var Procedure = require("procedure.js");
-var Symbol = require("symbol.js");
-var Type = require("type.js");
-
-var stdSymbols = function(){
-    var symbols = {};
-    for(var t in Type.basic){
-        var type = Type.basic[t];
-        symbols[type.name()] = new Symbol.Symbol(type.name(), new Type.TypeId(type));
-    }
-    symbols["LONGREAL"] = new Symbol.Symbol("LONGREAL", new Type.TypeId(Type.basic.real));
-    
-    var predefined = Procedure.predefined;
-    for(var i = 0; i < predefined.length; ++i){
-        var s = predefined[i];
-        symbols[s.id()] = s;
-    }
-    return symbols;
-}();
-
-var Scope = Class.extend({
-    init: function Scope(id){
-        this.__id = id;
-        this.__symbols = {};
-        for(var p in stdSymbols)
-            this.__symbols[p] = stdSymbols[p];
-        this.__unresolved = [];
-    },
-    id: function(){return this.__id;},
-    addSymbol: function(symbol){
-        var id = symbol.id();
-        if (this.findSymbol(id))
-            throw new Errors.Error( "'" + id + "' already declared");
-        this.__symbols[id] = symbol;
-    },
-    addType: function(type, id){
-        if (!id)
-            return undefined;
-
-        var symbol = new Symbol.Symbol(id.id(), type);
-        this.addSymbol(symbol, id.exported());
-        return symbol;
-    },
-    resolve: function(symbol){
-        var id = symbol.id();
-        var i = this.__unresolved.indexOf(id);
-        if (i != -1){
-            var info = symbol.info();
-            var type = info.type();
-            if (type !== undefined && !(type instanceof Type.Record))
-                throw new Errors.Error(
-                    "'" + id + "' must be of RECORD type because it was used before in the declation of POINTER");
-            this.__unresolved.splice(i, 1);
-        }
-    },
-    findSymbol: function(ident){return this.__symbols[ident];},
-    addUnresolved: function(id){
-        if (this.__unresolved.indexOf(id) == -1)
-            this.__unresolved.push(id);
-    },
-    unresolved: function(){return this.__unresolved;}
-});
-
-var ProcedureScope = Scope.extend({
-    init: function ProcedureScope(){
-        Scope.prototype.init.call(this, "procedure");
-    },
-    addSymbol: function(symbol, exported){
-        if (exported)
-            throw new Errors.Error("cannot export from within procedure: " 
-                + symbol.info().idType() + " '" + symbol.id() + "'");
-        Scope.prototype.addSymbol.call(this, symbol, exported);
-    }
-});
-
-var CompiledModule = Type.Module.extend({
-    init: function Scope$CompiledModule(id){
-        Type.Module.prototype.init.call(this, id);
-        this.__exports = {};
-    },
-    defineExports: function(exports){
-        for(var id in exports){
-            var symbol = exports[id];
-            if (symbol.isVariable())
-                symbol = new Symbol.Symbol(
-                    id,
-                    new Type.ExportedVariable(symbol.info()));
-            this.__exports[id] = symbol;
-        }
-    },  
-    findSymbol: function(id){
-        var s = this.__exports[id];
-        if (!s)
-            return undefined;
-        return new Symbol.Found(s);
-    }
-});
-
-var Module = Scope.extend({
-    init: function Scope$Module(name){
-        Scope.prototype.init.call(this, "module");
-        this.__name = name;
-        this.__exports = {};
-        this.__stripTypes = [];
-        this.__symbol = new Symbol.Symbol(name, new CompiledModule(name));
-        this.addSymbol(this.__symbol);
-    },
-    module: function(){return this.__symbol;},
-    addSymbol: function(symbol, exported){
-        Scope.prototype.addSymbol.call(this, symbol, exported);
-        if (exported)
-            this.__exports[symbol.id()] = symbol;
-    },
-    addType: function(type, id){
-        var result = Scope.prototype.addType.call(this, type, id);
-        if (!id || !id.exported())
-            this.__stripTypes.push(type);
-        return result;
-    },
-    exports: function(){return this.__exports;},
-    strip: function(){
-        for(var i = 0; i < this.__stripTypes.length; ++i)
-            this.__stripTypes[i].strip();
-    }
-});
-
-exports.Procedure = ProcedureScope;
-exports.Module = Module;

+ 0 - 31
snapshot/symbol.js

@@ -1,31 +0,0 @@
-"use strict";
-
-var Class = require("rtl.js").Class;
-var Errors = require("errors.js");
-var Type = require("type.js");
-
-var Symbol = Class.extend({
-	init: function Symbol(id, info){
-		this.__id = id;
-		this.__info = info;
-	},
-	id: function(){return this.__id;},
-	info: function(){return this.__info;},
-	isModule: function(){return this.__info instanceof Type.Module;},
-	isVariable: function(){return this.__info instanceof Type.Variable;},
-	isConst: function(){return this.__info instanceof Type.Const;},
-	isType: function(){return this.__info instanceof Type.TypeId;},
-	isProcedure: function(){return this.__info instanceof Type.Procedure;}
-});
-
-var FoundSymbol = Class.extend({
-    init: function(symbol, scope){
-        this.__symbol = symbol;
-        this.__scope = scope;
-    },
-    symbol: function(){return this.__symbol;},
-    scope: function(){return this.__scope;}
-});
-
-exports.Symbol = Symbol;
-exports.Found = FoundSymbol;

+ 0 - 234
snapshot/type.js

@@ -1,234 +0,0 @@
-"use strict";
-
-var Class = require("rtl.js").Class;
-var Errors = require("errors.js");
-
-var Id = Class.extend({
-    init: function Id(){}
-});
-
-var Type = Id.extend({
-    init: function Type(){
-        Id.prototype.init.call(this);
-    }
-});
-
-var TypeId = Id.extend({
-    init: function TypeId(type){
-        Id.prototype.init.call(this);
-        this._type = type;
-    },
-    type: function(){return this._type;},
-    description: function(){return 'type ' + this._type.description();},
-    strip: function(){
-        this._type = this._type instanceof Record 
-                   ? new NonExportedRecord(this._type.cons(), this._type.scope(), this._type.baseType())
-                   : undefined;
-    }
-});
-
-var ForwardTypeId = TypeId.extend({
-    init: function Type$ForwardTypeId(resolve){
-        TypeId.prototype.init.call(this);
-        this.__resolve = resolve;
-    },
-    type: function(){
-        if (!this._type)
-            this._type = this.__resolve();
-        return this._type;
-    }
-});
-
-var LazyTypeId = TypeId.extend({
-    init: function LazyTypeId(){
-        TypeId.prototype.init.call(this);
-    },
-    define: function(type){return this._type = type;}
-});
-
-exports.String = Type.extend({
-    init: function TypeString(s){
-        Type.prototype.init.call(this);
-        this.__s = s;
-    },
-    idType: function(){return "string";},
-    description: function(){return (this.__s.length == 1 ? "single-" : "multi-") + "character string";},
-    value: function(){return this.__s;},
-    asChar: function(){return this.__s.length == 1 ? this.__s.charCodeAt(0) : undefined;},
-    length: function(){return this.__s.length;}
-});
-
-var BasicType = Type.extend({
-    init: function BasicType(name, initValue){
-        Type.prototype.init.call(this);
-        this.__name = name;
-        this.__initValue = initValue;
-    },
-    idType: function(){return "type";},
-    name: function() {return this.__name;},
-    description: function(){return this.name();},
-    initializer: function(context){return this.__initValue;}
-});
-
-exports.Basic = BasicType;
-
-function foldArrayDimensions(a){
-    var result = a.length();
-    var next = a.elementsType();
-    if (result !== undefined
-        && next instanceof ArrayType){
-        var r = foldArrayDimensions(next);
-        return [result + ", " + r[0], r[1]];
-    }
-    return [result, next.description()];
-}
-
-var ArrayType = BasicType.extend({
-    init: function ArrayType(name, initializer, elementsType, size){
-        BasicType.prototype.init.call(this, name, initializer);
-        this.__elementsType = elementsType;
-        this.__size = size;
-    },
-    elementsType: function(){return this.__elementsType;},
-    length: function(){return this.__size;},
-    description: function(){
-        if (this.__elementsType === undefined) // special arrays, see procedure "LEN"
-            return this.name();
-        var desc = foldArrayDimensions(this);
-        var sizes = (desc[0] === undefined ? "" : " " + desc[0]);
-        return "ARRAY" + sizes + " OF " + desc[1];
-    }
-});
-
-exports.Pointer = BasicType.extend({
-    init: function PointerType(name, base){
-        BasicType.prototype.init.call(this, name, "null");
-        this.__base = base;
-    },
-    description: function(){
-        return this.name() || "POINTER TO " + this.baseType().description();
-    },
-    baseType: function(){return this.__base.type();}
-});
-
-var Record = BasicType.extend({
-    init: function Type$Record(name, cons, scope){
-        BasicType.prototype.init.call(this, name);
-        this.__cons = cons;        
-        this.__scope = scope;
-        this.__fields = {};
-        this.__base = undefined;
-    },
-    initializer: function(context){
-        return "new " + context.qualifyScope(this.__scope) + this.__cons + "()";
-    },
-    scope: function(){return this.__scope;},
-    cons: function(){return this.__cons;},
-    addField: function(field, type){
-        var name = field.id();
-        if (this.__fields.hasOwnProperty(name))
-            throw new Errors.Error("duplicated field: '" + name + "'");
-        if (this.__base && this.__base.findSymbol(name))
-            throw new Errors.Error("base record already has field: '" + name + "'");
-        this.__fields[name] = type;
-    },
-    ownFields: function() {return this.__fields;},
-    findSymbol: function(field){
-        var result = this.__fields[field];
-        if ( !result && this.__base)
-            result = this.__base.findSymbol(field);
-        return result;
-    },
-    baseType: function() {return this.__base;},
-    setBaseType: function(type) {this.__base = type;},
-    description: function(){
-        return this.name() || "anonymous RECORD";
-    }
-});
-
-var NonExportedRecord = Record.extend({
-    init: function Scope$NonExportedRecord(cons, scope, base){
-        Record.prototype.init.call(this, undefined, cons, scope);
-        this.setBaseType(base);
-    }
-});
-
-var NilType = Type.extend({
-    init: function NilType(){Type.prototype.init.call(this);},
-    idType: function(){return "NIL";},
-    description: function(){return "NIL";}
-});
-
-var basic = {
-    bool: new BasicType("BOOLEAN", false),
-    ch: new BasicType("CHAR", 0),
-    integer: new BasicType("INTEGER", 0),
-    real: new BasicType("REAL", 0),
-    set: new BasicType("SET", 0)
-};
-exports.basic = basic;
-exports.numeric = [basic.integer, basic.real];
-
-exports.nil = new NilType();
-
-exports.Const = Id.extend({
-    init: function Const(type, value){
-        Id.prototype.init.call(this);
-        this.__type = type;
-        this.__value = value;
-    },
-    idType: function(){return "constant";},
-    type: function(){return this.__type;},
-    value: function(){return this.__value;}
-});
-
-var Variable = Id.extend({
-    init: function Variable(type, isReadOnly){
-        Id.prototype.init.call(this);
-        this.__type = type;
-        this.__isReadOnly = isReadOnly;
-    },
-    idType: function(){return this.__isReadOnly ? "read-only variable" : "variable";},
-    type: function(){return this.__type;},
-    isReadOnly: function(){return this.__isReadOnly;}
-});
-
-var VariableRef = Variable.extend({
-    init: function Type$VariableRef(type){
-        Variable.prototype.init.call(this, type, false);
-    }
-});
-
-var ExportedVariable = Variable.extend({
-    init: function ExportedVariable(variable){
-        Variable.prototype.init.call(this, variable.type(), true);
-    },
-    idType: function(){return "imported variable";}
-});
-
-exports.Procedure = BasicType.extend({
-    init: function Procedure(name){
-        BasicType.prototype.init.call(this, name, "null");
-    },
-    idType: function(){return "procedure";}
-});
-
-var Module = Id.extend({
-    init: function Type$Module(name){
-        Id.prototype.init.call(this);
-        this.__name = name;
-    },
-    name: function(){return this.__name;}
-});
-
-exports.Array = ArrayType;
-exports.Variable = Variable;
-exports.VariableRef = VariableRef;
-exports.ExportedVariable = ExportedVariable;
-exports.Module = Module;
-exports.NonExportedRecord = NonExportedRecord;
-exports.Record = Record;
-exports.Type = Type;
-exports.TypeId = TypeId;
-exports.ForwardTypeId = ForwardTypeId;
-exports.LazyTypeId = LazyTypeId;