MODULE Module; IMPORT Code, Context, Errors, JsArray, LanguageContext, Procedure, Symbols, Types; TYPE Type* = RECORD(Types.Module) PROCEDURE findSymbol(id: STRING): Symbols.PFoundSymbol END; PType* = POINTER TO Type; AnyType* = RECORD(Types.StorageType) PROCEDURE callGenerator(cx: LanguageContext.PType): Procedure.PCallGenerator; PROCEDURE denote(id: STRING): Types.PField; PROCEDURE designatorCode(id: STRING): STRING; asField: POINTER TO AnyField; asVar: Types.PId END; AnyField = RECORD(Types.Field) END; AnyTypeProc* = RECORD(Types.DefinedProcedure) END; JS = RECORD(Type) END; VAR doProcId, varTypeId: STRING; any: POINTER TO AnyType; anyProc: AnyTypeProc; doProcSymbol, varTypeSymbol: Symbols.PSymbol; PROCEDURE AnyType.description(): STRING; RETURN "JS.var" END AnyType.description; PROCEDURE AnyType.initializer(cx: Context.Type; forNew: BOOLEAN): STRING; RETURN "undefined" END AnyType.initializer; PROCEDURE AnyType.callGenerator(cx: LanguageContext.PType): Procedure.PCallGenerator; RETURN Procedure.makeProcCallGenerator(cx, anyProc) END AnyType.callGenerator; PROCEDURE AnyType.denote(id: STRING): Types.PField; RETURN any.asField END AnyType.denote; PROCEDURE AnyType.designatorCode(id: STRING): STRING; RETURN id END AnyType.designatorCode; PROCEDURE AnyField.id(): STRING; RETURN "any field" END AnyField.id; PROCEDURE AnyField.exported(): BOOLEAN; RETURN FALSE END AnyField.exported; PROCEDURE AnyField.type(): Types.PType; RETURN any END AnyField.type; PROCEDURE AnyField.asVar(): Types.PId; RETURN any.asVar END AnyField.asVar; PROCEDURE AnyTypeProc.args(): JsArray.Type; RETURN NIL END AnyTypeProc.args; PROCEDURE AnyTypeProc.result(): Types.PType; RETURN any END AnyTypeProc.result; PROCEDURE JS.findSymbol(id: STRING): Symbols.PFoundSymbol; VAR result: Symbols.PSymbol; BEGIN IF id = doProcId THEN result := doProcSymbol; ELSIF id = varTypeId THEN result := varTypeSymbol; ELSE result := Symbols.makeSymbol(id, Types.makeProcedure(any)); END; RETURN Symbols.makeFound(result, NIL) END JS.findSymbol; PROCEDURE makeVarTypeSymbol(): Symbols.PSymbol; RETURN Symbols.makeSymbol(varTypeId, Types.makeTypeId(any)) END makeVarTypeSymbol; PROCEDURE makeDoProcSymbol(): Symbols.PSymbol; TYPE Call = RECORD(Procedure.StdCall) END; Proc = RECORD(Procedure.Std) END; VAR description: STRING; call: POINTER TO Call; proc: POINTER TO Proc; PROCEDURE Call.make(args: JsArray.Type; cx: LanguageContext.Type): Code.PExpression; VAR arg: Code.PExpression; type: Types.PType; BEGIN arg := Procedure.checkSingleArgument(args, SELF, cx.types); type := arg.type(); IF ~(type IS Types.PString) THEN Errors.raise("string is expected as an argument of " + description + ", got " + type.description()); END; RETURN Code.makeSimpleExpression(Types.stringValue(type(Types.PString)^), NIL) END Call.make; PROCEDURE Proc.description(): STRING; RETURN description END Proc.description; BEGIN description := "JS predefined procedure 'do'"; NEW(call); Procedure.initStdCall(call); Procedure.hasArgumentWithCustomType(call); NEW(proc); Procedure.initStd("", call, proc^); RETURN Procedure.makeSymbol(proc) END makeDoProcSymbol; PROCEDURE makeJS*(): PType; VAR result: POINTER TO JS; BEGIN NEW(result); Types.initModule(result^, "this"); RETURN result END makeJS; BEGIN doProcId := "do$"; varTypeId := "var$"; NEW(any); NEW(any.asField); any.asVar := Types.makeTypeId(any); doProcSymbol := makeDoProcSymbol(); varTypeSymbol := makeVarTypeSymbol(); END Module.