123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- import {
- FunctionCall,
- Literal,
- UnaryApp,
- InfixApp,
- IntLiteral,
- RealLiteral,
- StringLiteral,
- VariableLiteral,
- ArrayAccess,
- BoolLiteral
- } from "./../ast/expressions";
- import { Types } from "./../typeSystem/types";
- import { ArrayType } from "./../typeSystem/array_type";
- import {
- resultTypeAfterInfixOp,
- resultTypeAfterUnaryOp
- } from "./../processor/compatibilityTable";
- import { LanguageDefinedFunction } from "./../processor/definedFunctions";
- export class BaseConverter {
- constructor (ivprogAST) {
- this.ivprogAST = ivprogAST;
- this.globalMap = new Map();
- this.symbolMap = [];
- this.symbolMap.push(this.globalMap);
- }
- popContext () {
- if (this.symbolMap.length > 1) {
- this.symbolMap.pop();
- }
- }
- pushContext (map) {
- this.symbolMap.push(map);
- }
- findFunction (name) {
- if (name.match(/^\$.+$/)) {
- const fun = LanguageDefinedFunction.getFunction(name);
- return fun;
- } else {
- const val = this.ivprogAST.functions.find(v => v.name === name);
- return val;
- }
- }
- findSymbol (id) {
- for (let i = this.symbolMap.length - 1; i >= 0; i -= 1) {
- const map = this.symbolMap[i];
- if (map.has(id)) {
- return map.get(id);
- }
- }
- return null;
- }
- insertGlobalSymbol (id, declaration) {
- this.globalMap.set(id, { id: id, type: declaration.type, global: true });
- }
- insertSymbol (id, declaration) {
- const map = this.symbolMap.slice(-1)[0];
- map.set(id, { id: id, type: declaration.type, global: false });
- }
- evaluateExpressionType (expression) {
- if (expression instanceof UnaryApp) {
- const op = expression.op;
- const resultType = this.evaluateExpressionType(expression.left);
- const finalResult = resultTypeAfterUnaryOp(op, resultType);
- return finalResult;
- } else if (expression instanceof InfixApp) {
- const op = expression.op;
- const resultTypeLeft = this.evaluateExpressionType(expression.left);
- const resultTypeRight = this.evaluateExpressionType(expression.right);
- const finalResult = resultTypeAfterInfixOp(
- op,
- resultTypeLeft,
- resultTypeRight
- );
- return finalResult;
- } else if (expression instanceof Literal) {
- return this.evaluateLiteralType(expression);
- } else if (expression instanceof FunctionCall) {
- const fun = this.findFunction(expression.id);
- return fun.returnType;
- } else if (expression instanceof ArrayAccess) {
- const arrayTypeInfo = this.findSymbol(expression.id);
- const arrType = arrayTypeInfo.type;
- if (expression.column !== null) {
- // indexing matrix
- return arrType.innerType;
- } else {
- if (arrayTypeInfo.columns === null) {
- return arrType.innerType;
- }
- return new ArrayType(arrType.innerType, 1);
- }
- }
- }
- evaluateLiteralType (literal) {
- if (literal instanceof IntLiteral) {
- return literal.type;
- } else if (literal instanceof RealLiteral) {
- return literal.type;
- } else if (literal instanceof StringLiteral) {
- return literal.type;
- } else if (literal instanceof BoolLiteral) {
- return literal.type;
- } else if (literal instanceof VariableLiteral) {
- const typeInfo = this.findSymbol(literal.id);
- return typeInfo.type;
- } else {
- console.warn("Evaluating type only for an array literal...");
- // This should never happen in this context and there is no use throwing execeptions!
- return new ArrayType(Types.INTEGER, 1);
- }
- }
- }
|