123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- 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.bind(this)();
- },
- idType: function(){return "type";},
- isProcedure: function(){return false;}
- });
- exports.Type = Type;
- exports.String = Type.extend({
- init: function TypeString(s){
- Type.prototype.init.bind(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;}
- });
- var BasicType = Type.extend({
- init: function BasicType(name, initValue){
- Type.prototype.init.bind(this)();
- this.__name = name;
- this.__initValue = initValue;
- },
- name: function() {return this.__name;},
- description: function(){return this.name();},
- initializer: function() {return this.__initValue;}
- });
- exports.Basic = BasicType;
- exports.Array = BasicType.extend({
- init: function ArrayType(name, initializer, elementsType, size){
- BasicType.prototype.init.bind(this)(name, initializer);
- this.__elementsType = elementsType;
- this.__size = size;
- },
- elementsType: function(){return this.__elementsType;},
- arraySize: function(){return this.__size;}
- });
- exports.Pointer = BasicType.extend({
- init: function PointerType(name, base){
- BasicType.prototype.init.bind(this)(name, "null");
- this.__base = base;
- },
- description: function(){
- var name = this.name();
- if (name.indexOf("$") != -1)
- return "POINTER TO " + this.baseType().description();
- return name;
- },
- baseType: function(){
- if (this.__base instanceof exports.ForwardRecord)
- this.__base = this.__base.resolve();
- return this.__base;
- }
- });
- exports.ForwardRecord = Type.extend({
- init: function(resolve){
- Type.prototype.init.bind(this)();
- this.__resolve = resolve;
- },
- resolve: function(){return this.__resolve();}
- });
- exports.Record = BasicType.extend({
- init: function RecordType(name){
- BasicType.prototype.init.bind(this)(name, "new " + name + "()");
- this.__fields = {};
- this.__base = undefined;
- this.__finalized = false;
- },
- addField: function(field, type){
- if (this.__fields.hasOwnProperty(field))
- throw new Errors.Error("duplicated field: '" + field + "'");
- if (this.__base && this.__base.findSymbol(field))
- throw new Errors.Error("base record already has field: '" + field + "'");
- this.__fields[field] = 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;},
- finalize: function(){this.__finalized = true;},
- description: function(){
- var name = this.name();
- if (name.indexOf("$") != -1)
- return "anonymous RECORD";
- return name;
- }
- });
- var NilType = Type.extend({
- init: function NilType(){Type.prototype.init.bind(this)();},
- idType: function(){return "NIL";},
- description: function(){return "NIL";}
- });
- exports.basic = {
- bool: new BasicType("BOOLEAN", false),
- char: new BasicType("CHAR", 0),
- int: new BasicType("INTEGER", 0),
- real: new BasicType("REAL", 0),
- set: new BasicType("SET", 0)
- };
- exports.nil = new NilType();
- exports.Const = Id.extend({
- init: function Const(type, value){
- Id.prototype.init.bind(this)();
- this.__type = type;
- this.__value = value;
- },
- idType: function(){return "constant";},
- type: function(){return this.__type;},
- value: function(){return this.__value;}
- });
- exports.Variable = Id.extend({
- init: function Variable(type, isVar, isReadOnly){
- Id.prototype.init.bind(this)();
- this.__type = type;
- this.__isVar = isVar;
- this.__isReadOnly = isReadOnly;
- },
- idType: function(){return this.__isReadOnly ? "read-only variable" : "variable";},
- type: function(){return this.__type;},
- isVar: function(){return this.__isVar;},
- isReadOnly: function(){return this.__isReadOnly;}
- });
- exports.Procedure = Id.extend({
- init: function Procedure(type){
- Id.prototype.init.bind(this)();
- this.__type = type;
- },
- idType: function(){return "procedure";},
- type: function(){return this.__type;}
- });
- 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;},
- isVariable: function(){return this.__info instanceof exports.Variable;},
- isConst: function(){return this.__info instanceof exports.Const;},
- isType: function(){return this.__info instanceof Type;},
- isProcedure: function(){return this.__info instanceof exports.Procedure;},
- });
- exports.Symbol = Symbol;
|