123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- MODULE LanguageContext;
- IMPORT Chars, CodeGenerator, Context, Designator, Errors, Expression, OberonRtl, Record, Symbols, T := Types, Variable;
- TYPE
- PType* = POINTER TO Type;
- CastOp* = RECORD
- PROCEDURE make*(cx: PType; e: Expression.PType): Expression.PType;
- PROCEDURE assign*(cx: PType; info: T.PVariable; right: Expression.PType): STRING;
- PROCEDURE clone*(cx: PType; e: Expression.PType): STRING;
- END;
- PCastOp* = POINTER TO CastOp;
- Types* = RECORD
- PROCEDURE implicitCast*(from, to: T.PType; toVar: BOOLEAN; VAR op: PCastOp): INTEGER;
- PROCEDURE typeInfo*(type: T.PType): STRING;
- PROCEDURE isRecursive*(type, base: T.PType): BOOLEAN;
- PROCEDURE makeOpenArray*(type: T.PType): T.PStorageType;
- PROCEDURE makeStaticArray*(type: T.PType; init: STRING; length: INTEGER): T.PStorageType;
- END;
- PTypes* = POINTER TO Types;
- ModuleGenerator* = RECORD
- PROCEDURE prolog*(): STRING;
- PROCEDURE epilog*(exports: Symbols.Map): STRING;
- END;
- PModuleGenerator* = POINTER TO ModuleGenerator;
- CodeTraits* = RECORD
- PROCEDURE CodeTraits*(code: CodeGenerator.PIGenerator; rtl: OberonRtl.PType; checkIndexes: BOOLEAN);
- PROCEDURE generator*(): CodeGenerator.PIGenerator;
- PROCEDURE getAt*(e, index: STRING; type: T.PStorageType): STRING;
- PROCEDURE putAt*(where, index, what: STRING): STRING;
- PROCEDURE referenceCode*(VAR info: T.Id): STRING;
- PROCEDURE assign*(VAR info: T.Id; right: Expression.PType): STRING;
- code: CodeGenerator.PIGenerator;
- rtl: OberonRtl.PType;
- checkIndexes: BOOLEAN;
- END;
- Imports = MAP OF STRING;
- Language* = RECORD
- moduleResolver-: PROCEDURE(name: STRING): T.PModule;
- PROCEDURE moduleGenerator*(name: STRING; imports: Imports): PModuleGenerator;
- rtl-: OberonRtl.PType;
- codeTraits-: POINTER TO CodeTraits;
- types-: PTypes;
- stdSymbols-: Symbols.Map;
- END;
- PLanguage* = POINTER TO Language;
- Type* = RECORD
- PROCEDURE Type*(language: PLanguage; cx: Context.PType);
- language-: PLanguage;
- cx-: Context.PType;
- END;
- PROCEDURE Type.Type(language: PLanguage; cx: Context.PType)
- | language(language),
- cx(cx);
- END;
- PROCEDURE CodeTraits.CodeTraits(code: CodeGenerator.PIGenerator; rtl: OberonRtl.PType; checkIndexes: BOOLEAN)
- | code(code),
- rtl(rtl),
- checkIndexes(checkIndexes);
- END;
- PROCEDURE CodeTraits.generator(): CodeGenerator.PIGenerator;
- RETURN SELF.code;
- END;
- PROCEDURE CodeTraits.getAt(e, index: STRING; type: T.PStorageType): STRING;
- VAR
- r: STRING;
- BEGIN
- IF ~SELF.checkIndexes THEN
- IF type = T.basic.ch THEN
- r := e + ".charCodeAt(" + index + ")";
- ELSE
- r := e + "[" + index + "]";
- END;
- ELSE
- IF type = T.basic.ch THEN
- r := SELF.rtl.charAt(e, index);
- ELSE
- r := SELF.rtl.getAt(e, index);
- END;
- END;
- RETURN r;
- END;
- PROCEDURE CodeTraits.putAt(where, index, what: STRING): STRING;
- VAR
- r: STRING;
- BEGIN
- IF ~SELF.checkIndexes THEN
- r := where + "[" + index + "] = " + what;
- ELSE
- r := SELF.rtl.putAt(where, index, what);
- END;
- RETURN r;
- END;
- PROCEDURE CodeTraits.referenceCode(VAR info: T.Id): STRING;
- VAR
- result: STRING;
- BEGIN
- IF info IS T.DeclaredVariable THEN
- result := CodeGenerator.mangleId(info.id());
- IF info.type().isScalar() & ~((info IS Variable.ArgumentVariable) & info.var) THEN
- result := "{set: function($v){" + result + " = $v;}, get: function(){return " + result + ";}}";
- END
- ELSIF info IS Variable.PropertyVariable THEN
- IF info.type().isScalar() THEN
- result := SELF.rtl.makeRef(info.leadCode, info.propCode);
- ELSE
- result := SELF.getAt(info.leadCode, info.propCode, info.type());
- END;
- ELSIF info IS Variable.DerefVariable THEN
- result := info.code;
- ELSIF info IS Record.FieldVariable THEN
- codeId <- Record.mangleField(info.field.id());
- IF info.type().isScalar() THEN
- result := SELF.rtl.makeRef(info.leadCode,
- Chars.doubleQuote + codeId + Chars.doubleQuote);
- ELSE
- result := info.leadCode + "." + codeId;
- END;
- ELSE
- Errors.raise("cannot reference " + info.idType());
- END;
- RETURN result;
- END;
- PROCEDURE CodeTraits.assign(VAR info: T.Id; right: Expression.PType): STRING;
- VAR
- result: STRING;
- BEGIN
- rightCode <- Expression.deref(right).code();
- IF info IS T.DeclaredVariable THEN
- idCode <- CodeGenerator.mangleId(info.id());
- IF (info IS Variable.ArgumentVariable) & info.var THEN
- result := idCode + ".set(" + rightCode + ")";
- ELSE
- result := idCode + " = " + rightCode;
- END;
- ELSIF info IS Variable.PropertyVariable THEN
- result := SELF.putAt(info.leadCode, info.propCode, rightCode);
- ELSIF info IS Record.FieldVariable THEN
- result := info.leadCode + "." + Record.mangleField(info.field.id()) + " = " + rightCode;
- END;
- RETURN result;
- END;
- END LanguageContext.
|