@composita/compiler
Version:
Composita language compiler.
71 lines • 5.21 kB
JavaScript
import { ProcedureSymbol, BuiltInTypeSymbol, ConstantSymbol, InterfaceDeclarationSymbol, CardinalitySymbol, VariableSymbol, SearchOptions, } from '../symbols/symbols';
import { TypeRegisterVisitor } from './register-types';
export class SymbolConstruction {
constructor(symbolTable, programScope) {
this.symbolTable = symbolTable;
this.programScope = programScope;
const bool_t = new BuiltInTypeSymbol(this.symbolTable.globalScope, 'BOOLEAN');
const char_t = new BuiltInTypeSymbol(this.symbolTable.globalScope, 'CHARACTER');
const text_t = new BuiltInTypeSymbol(this.symbolTable.globalScope, 'TEXT');
const int_t = new BuiltInTypeSymbol(this.symbolTable.globalScope, 'INTEGER');
const real_t = new BuiltInTypeSymbol(this.symbolTable.globalScope, 'REAL');
this.builtInTypes = new Array(bool_t, char_t, text_t, int_t, real_t);
this.constants = new Map([
['TRUE', bool_t],
['FALSE', bool_t],
['PI', real_t],
]);
this.variables = new Map([['TIME', int_t]]);
this.systemProcedures = new Array(
// propper procedures
['ASSERT', [this.symbolTable.voidType, new Array(bool_t)]], ['ASSERT', [this.symbolTable.voidType, new Array(bool_t, int_t)]], ['HALT', [this.symbolTable.voidType, new Array(int_t)]], ['INC', [this.symbolTable.voidType, new Array(int_t)]], ['INC', [this.symbolTable.voidType, new Array(int_t, int_t)]], ['DEC', [this.symbolTable.voidType, new Array(int_t)]], ['DEC', [this.symbolTable.voidType, new Array(int_t, int_t)]], ['PASSIVATE', [this.symbolTable.voidType, new Array(int_t)]], ['WRITE', [this.symbolTable.voidType, new Array(text_t)]], ['WRITE', [this.symbolTable.voidType, new Array(int_t)]], ['WRITE', [this.symbolTable.voidType, new Array(real_t)]], ['WRITE', [this.symbolTable.voidType, new Array(char_t)]], ['WRITEHEX', [this.symbolTable.voidType, new Array(int_t)]], ['WRITELINE', [this.symbolTable.voidType, new Array()]],
// alloc and dealloc
['NEW', [this.symbolTable.voidType, new Array(this.symbolTable.anyComponentType)]], ['NEW', [this.symbolTable.voidType, new Array(int_t)]], ['NEW', [this.symbolTable.voidType, new Array(int_t, int_t)]], ['NEW', [this.symbolTable.voidType, new Array(int_t, int_t, int_t)]], ['DELETE', [this.symbolTable.voidType, new Array(this.symbolTable.anyComponentType)]],
// function procedures
['COUNT', [int_t, new Array(this.symbolTable.anyRequiredInterfaceType)]], ['LENGTH', [int_t, new Array(text_t)]], ['SQRT', [real_t, new Array(real_t)]], ['SIN', [real_t, new Array(real_t)]], ['COS', [real_t, new Array(real_t)]], ['TAN', [real_t, new Array(real_t)]], ['ARCSIN', [real_t, new Array(real_t)]], ['ARCCOS', [real_t, new Array(real_t)]], ['ARCTAN', [real_t, new Array(real_t)]], ['RANDOM', [int_t, new Array(int_t, int_t)]], ['MIN', [real_t, new Array(real_t)]], ['MIN', [int_t, new Array(int_t)]], ['MAX', [real_t, new Array(real_t)]], ['MAX', [int_t, new Array(int_t)]],
// type conversion
['CHARACTER', [char_t, new Array(int_t)]], ['INTEGER', [int_t, new Array(real_t)]], ['INTEGER', [int_t, new Array(char_t)]], ['REAL', [real_t, new Array(int_t)]], ['TEXT', [text_t, new Array(char_t)]]);
}
static run(symbolTable, program, scope) {
const construction = new SymbolConstruction(symbolTable, scope);
construction.register(program);
}
register(program) {
this.registerBuiltIns();
program.accept(new TypeRegisterVisitor(this.symbolTable, this.programScope));
}
registerBuiltIns() {
this.registerBuiltInTypes();
this.registerBuiltInProcedures();
this.registerBuiltInConstants();
this.registerBuiltInVariables();
}
registerBuiltInTypes() {
this.builtInTypes.forEach((value) => this.symbolTable.registerBuiltIns(value));
}
registerBuiltInProcedures() {
this.systemProcedures.forEach((value) => {
const procedure = new ProcedureSymbol(this.symbolTable.globalScope, value[0], value[1][1], value[1][0]);
this.symbolTable.registerProcedure(procedure);
});
}
registerBuiltInConstants() {
this.constants.forEach((value, key) => this.symbolTable.constants.push(new ConstantSymbol(key, value)));
}
registerBuiltInVariables() {
this.variables.forEach((value, key) => this.symbolTable.registerVariable(new VariableSymbol(this.symbolTable.globalScope, key, false, value)));
}
static createInterfaceDeclarationSymbol(symbolTable, node, scope) {
const name = node.getName().getName();
const interfaces = symbolTable.findInterface(name, new SearchOptions(scope, true, true));
if (interfaces.length === 0) {
throw new Error(`Interface ${name} not defined.`);
}
if (interfaces.length > 1) {
throw new Error(`Interface ${name} multiple times defined.`);
}
const cardinality = node.getCardinality();
return new InterfaceDeclarationSymbol(interfaces[0], new CardinalitySymbol(cardinality?.getMin() ?? 1, cardinality?.getMax()));
}
}
//# sourceMappingURL=symbol-construction.js.map