void SymbolTreeBuilder::visit(ReturnNode& node) { if (!_curFunctionDecl) { throw SemanticException("Return statement outside function scope\n", node); } const char* function_name = _curFunctionDecl->symbolName(); const FunctionType* func_type = cast_type<FunctionType>(_curFunctionDecl->symbolType()); const Type* func_return = func_type->typeOfReturnValue(); // current return type if (!func_return->isVoidType() && !node.expression()) { std::stringstream stream; stream <<"Function '" << function_name << "' has return type '" << func_return->typeString() << "', but we are not returning any" << std::endl; throw SemanticException(stream.str(), node); } if (node.expression()) { if (func_return->isVoidType()) { std::stringstream stream; stream <<"Function '" << function_name << "' has return type '" << func_return->typeString() << "', but we are returning type '" << _expResult.type->typeString() <<"'" << std::endl; throw SemanticException(stream.str(), node); } node.expression()->accept(*this); // check if the return types match if(!_expResult.type->isPromotableTo(func_return)) { std::stringstream stream; stream <<"Function '" << function_name << "' has return type '" << func_return->typeString() << "', but we are returning type '" << _expResult.type->typeString() <<"'" << std::endl; throw SemanticException(stream.str(), node); } _expResult.symbol->markReturnValue(); } node.setScope(currentScope()); node.setNodeType(_expResult.type); }
Tipo* ExprIgualQue::validarSemantico() { Tipo* t_expr1 = op1->validarSemantico(); Tipo* t_expr2 = op2->validarSemantico(); Tipo* tipo_entero = InformacionSemantica::GetInstance()->GetTablaTipos().find("INTEGER")->second; Tipo* tipo_cadena = InformacionSemantica::GetInstance()->GetTablaTipos().find("STRING")->second; if ( t_expr1->GetTipo() == t_entero || t_expr1->GetTipo()==t_real ) { if ( !(tipo_entero->EsEquivalente(t_expr2) ) ) throw SemanticException("La expresion solo es aplicable a tipos compatibles"); } else if ( t_expr1->GetTipo() == t_cadena || t_expr1->GetTipo()==t_caracter ) { if ( !(tipo_cadena->EsEquivalente(t_expr2) ) ) throw SemanticException("La expresion solo es aplicable a tipos compatibles"); } else if ( t_expr1->GetTipo() == t_boolean ) { if ( t_expr2->GetTipo() != t_boolean ) throw SemanticException("La expresion solo es aplicable a tipos compatibles"); } else throw SemanticException("La expresion no es aplicable a estos tipos"); return InformacionSemantica::GetInstance()->GetTablaTipos().find("BOOLEAN")->second; }
void SymbolTreeBuilder::visit(VariableAccessNode& node) { node.setScope(currentScope()); const char* symbol_name = node.variableName(); auto sym = _curScope->resolveSymbol(symbol_name); if (!sym) { std::stringstream stream; stream << "Symbol '" << symbol_name << "' is undefined" << std::endl; throw SemanticException(stream.str(), node); } if (!sym->isVariable()) { std::stringstream stream; stream << "Symbol '" << symbol_name << "' is not a variable" << std::endl; throw SemanticException(stream.str(), node); } _expResult = ExpressionResult(sym->symbolType(), sym); node.setNodeType(_expResult.type); node.setExpressionResult(_expResult); sym->touchRead(); }
Type *ExpressionFunctionNode::ValidateSemantic() { Type* IdType=SymbolTable::GetInstance()->GetVariableType(ID); if(IdType->Name.compare("Function")!=0) { throw SemanticException("Se esperaba un Arreglo ,Fila:"+to_string(Row)+",Columna:"+to_string(Column)); } if(dynamic_cast<FunctionType*>(IdType)->Params.size()!=this->Expressions->size()) { throw SemanticException("Dimension incoherente del arreglo,Fila:"+to_string(Row)+",Columna:"+to_string(Column)); } /* list<ExpressionNode*>::const_iterator iterator; ExpressionNode *e; for (iterator = Expressions->begin(); iterator != Expressions->end(); ++iterator) { e=*iterator; if((e->NameType.compare("Entero")!=0)) { throw SemanticException("Se esperaba tipo de dato entero,Fila:"+to_string(e->Row)+",Columna:"+to_string(e->Column)); } } */ return dynamic_cast<FunctionType*>(IdType)->ReturnType; }
void StatementAbrirArchivoNode::ValidateSemantic() { if(Expression->ValidateSemantic()->Name!="Cadena") { throw SemanticException("Se esperaba una Cadena ,Fila:"+to_string(Expression->Row)+",Columna:"+to_string(Expression->Column)); } Variable->ValidateSemantic(); if(Operators->size()>2) { throw SemanticException("Solo puede haber un Lectura y una Escritura:"+to_string(Expression->Row)+",Columna:"+to_string(Expression->Column)); } list<string>::const_iterator iterator; string temp; for (iterator = Operators->begin(); iterator != Operators->end(); ++iterator) { if(temp.compare("")!=0) { if(temp.compare(*iterator)==0){ throw SemanticException("Se esperaba tipo de dato entero,Fila:"+to_string(Row)+",Columna:"+to_string(Column)); } } temp=*iterator; } }
void SymbolTreeBuilder::visit(ArgumentDeclNode& node) { node.setScope(currentScope()); if (node.isCustomType()) { throw SemanticException("Custom types not yet supported!!!\n", node); } YAL_ASSERT(_curFunctionDecl); auto sym = _curScope->resolveSymbol(node.argumentName()); if (sym && sym->scope() == _curScope) { std::stringstream stream; stream <<"Variable '" << node.argumentName() << "' has already been declared as an argument" << std::endl; throw SemanticException(stream.str(), node); } Type* arg_data_type = node.argumentType(); if (node.isCustomType()) { /*sym = _curScope->resolveSymbol(node.argumentId()); if (!sym) { _formater.format("Could not find type '%s'\n", node.argumentId()); logError(node); return; } if (sym->isVariable()) { _formater.format("Symbol type '%s' cannot be a variable name\n", node.argumentId()); logError(node); return; } arg_data_type = sym->astNode()->nodeType();*/ } const Symbol* result = _curScope->declareSymbol(node.argumentName(), arg_data_type, Symbol::kFlagAssignable | Symbol::kFlagFunctionParam | Symbol::kFlagVariable); (void) result; YAL_ASSERT(result); node.setNodeType(arg_data_type); }
Node* Parser::PostfixExpr() { Node *left = PrimaryExpr(); if(oper == ROUND_LEFT_BRACKET) { if( !simple && symStack->FindVar(left->GetName())->GetSymType() != FUNCTION ) throw SemanticException(currentToken, "Term not a function"); Next(); Node *args = ArgumentExprList(); if(oper != ROUND_RIGHT_BRACKET) throw ParserException(currentToken, "Postfix expression without ')'"); Next(); SymbolType type = ( (SymFunction*)( symStack->FindVar(left->GetName()) ) )->GetReturnType(); return new NodeCall(type, left->GetName(), args); } if(oper == SQUARE_LEFT_BRACKET) { if( !simple && symStack->FindVar(left->GetName())->GetSymType() != ARRAY ) throw SemanticException(currentToken, "Term not an array"); Next(); Node *link = Expression(); if(oper == SQUARE_RIGHT_BRACKET) { Next(); return new NodeBinary(left, ARRAY_INDEX, link); } else throw ParserException(currentToken, "No ']'"); } if(oper == OPER_POINT || oper == OPER_ARROW) { TokenValue _oper = oper; Next(); Node *right = PrimaryExpr(); if(right == NULL) throw ParserException(currentToken, "No field"); return new NodeBinary(left, _oper, right); } if(oper == OPER_INC || oper == OPER_DEC) { TokenValue _oper = oper; Next(); return new NodeUnary(_oper, left); } return left; }
void SentenciaProcedimiento::validarSemantica() { Tipo* t = function->validarSemantico(); if ( t != NULL ) throw SemanticException("Esta intentando llamar una funcion como procedimiento"); }
Node* Parser::DirectDeclarator(Symbol *type) { if(currentToken->GetTokenType() == IDENTIFIER) { if( !simple && symStack->VarAt(text) ) throw SemanticException(currentToken, "Redefinition identifier"); string _oper = text; Next(); if(oper == SQUARE_LEFT_BRACKET) { Next(); int length = 0; if(currentToken->GetTokenType() == CONST_INTEGER) { length = atoi(text.c_str()); Next(); } else throw ParserException(currentToken, "Array declaration without length"); if(oper != SQUARE_RIGHT_BRACKET) throw ParserException(currentToken, "Array declaration without ']'"); symStack->AddVar(new SymTypeArray(type, _oper, length)); Next(); return new NodeVar(_oper); } if(oper != ROUND_LEFT_BRACKET) symStack->AddVar(new SymVar(type, _oper)); //symtable add return new NodeVar(_oper); } return NULL; }
Tipo* Resta::validarSemantico() { Tipo* t_expr1 = op1->validarSemantico(); Tipo* t_expr2 = op2->validarSemantico(); if ( t_expr1->GetTipo() == t_entero && t_expr2->GetTipo() == t_entero ) return t_expr1; if ( t_expr1->GetTipo() == t_entero && t_expr2->GetTipo()==t_real ) return t_expr2; if ( t_expr1->GetTipo() == t_real && t_expr2->GetTipo() == t_entero ) return t_expr1; if ( t_expr1->GetTipo() == t_real && t_expr2->GetTipo() == t_real) return t_expr2; if ( t_expr1->GetTipo() == t_caracter && t_expr2->GetTipo() == t_entero ) return t_expr1; if ( t_expr1->GetTipo() == t_entero && t_expr2->GetTipo() == t_caracter ) return t_expr2; throw SemanticException("Estos tipos no se les puede aplicar la resta"); }
void SymbolTreeBuilder::visit(CompareOperatorNode& node) { node.setScope(currentScope()); node.expressionLeft()->accept(*this); ExpressionResult left_type = _expResult; node.expressionRight()->accept(*this); // evaluate right type ExpressionResult right_type = _expResult; if (!right_type.type->isPromotableTo(left_type.type)) { std::stringstream stream; stream <<"Cannot convert right expression to left, expression type " << _expResult.type->typeString() <<" cannot be cast to " << left_type.type->typeString() << std::endl; throw SemanticException(stream.str(), node); } _expResult = left_type; Symbol* tmp_sym = _curScope->declareTemporarySymbol(_expResult.type); YAL_ASSERT(tmp_sym); _curStatment->addSymbolToScope(tmp_sym); _expResult = ExpressionResult(BuiltinType::GetBuiltinType(BuiltinType::kBool), tmp_sym); node.setNodeType(_expResult.type); node.setExpressionResult(_expResult); }
list<LimitesRango*> Sintactico::ParseDimensionList() { if ( proximo_token.GetTipo() == lit_int ) { int inf = atoi(proximo_token.GetLexema().c_str()); proximo_token = analizador_lexico->ObtenerSiguienteToken(); if ( proximo_token.GetTipo() == punt_doblepunto ) { proximo_token = analizador_lexico->ObtenerSiguienteToken(); if ( proximo_token.GetTipo() == lit_int ) { int sup = atoi( proximo_token.GetLexema().c_str() ); if ( inf > sup ) throw SemanticException("El indice inferior del arreglo debe ser menor o igual al superior"); proximo_token = analizador_lexico->ObtenerSiguienteToken(); list<LimitesRango*> lista_dim = _ParseDimensionList(); list<LimitesRango*>::iterator it = lista_dim.begin(); lista_dim.insert(it,new LimitesRango(inf,sup) ); return lista_dim; } else throw SyntaxException("No se encontro una constante entera",analizador_lexico->GetLineaActual()); } else throw SyntaxException("No se encontro el token de doble punto",analizador_lexico->GetLineaActual()); } else throw SyntaxException("No se encontro una constante entera",analizador_lexico->GetLineaActual()); }
void SymbolTreeBuilder::visit(ConditionNode& node) { node.setScope(currentScope()); if (node.hasConditionComponent()) { _curStatment = node.condition(); node.condition()->accept(*this); // check condition expression if (!_expResult.type->isPromotableToBoolean()) { throw SemanticException("Condition expression can not be promoted to boolean\n", node); } } if (node.hasOnTrueComponent()) { // begin new scope beginScope(); node.onTrue()->accept(*this); endScope(); } if (node.hasOnFalseComponent()) { // begin new scope beginScope(); node.onFalse()->accept(*this); endScope(); } }
Type *LessThanNode::ValidateSemantic() { Type* leftNode=LeftNode->ValidateSemantic(); Type* righNode=RightNode->ValidateSemantic(); BooleanType * b=new BooleanType(); if(leftNode->Name.compare("Entero")==0 && righNode->Name.compare("Entero")==0) { return b; }else if(leftNode->Name.compare("Entero")==0 && righNode->Name.compare("Real")==0) { return b; }else if(leftNode->Name.compare("Real")==0 && righNode->Name.compare("Entero")==0) { return b; }else if(leftNode->Name.compare("Caracter")==0 && righNode->Name.compare("Caracter")==0) { return b; }else if(leftNode->Name.compare("Cadena")==0 && righNode->Name.compare("Cadena")==0) { return b; }else if(leftNode->Name.compare("Booleano")==0 && righNode->Name.compare("Booleano")==0) { return b; }else { throw SemanticException("Tipos de dato incompatibles "+ leftNode->Name+"-"+righNode->Name+",Fila:"+to_string(Row)+",Columna:"+to_string(Column)); } }
void SymbolTreeBuilder::visit(FunctionDeclBaseNode& node) { node.setScope(currentScope()); const char* func_name = node.functionNameWithType(); auto sym = _curScope->resolveSymbol(func_name); if (sym) { std::stringstream stream; stream << "Symbol name '" << func_name << "' already delcared" << std::endl; throw SemanticException(stream.str(), node); } // check for object type if (node.isObjectFunction()) { Type* object_type = node.objectType(); if (object_type->isUndefined()) { std::stringstream stream; stream << "Function's object type '" << object_type->typeString() << "'" << "for function '" <<func_name << "' is undefined." << std::endl; throw SemanticException(stream.str(), node); } const char* builtin_function = object_type->builtinFunctionSymName(node.functionName()); if (builtin_function) { std::stringstream stream; stream << "Can not declare function '" << func_name << "'" << " for type '" <<object_type->typeString() << "' since it conflicts with a builtin function." << std::endl; throw SemanticException(stream.str(), node); } } }
Node* Parser::PrimaryExpr() { if(currentToken->GetTokenType() == IDENTIFIER) { string _text = text; Next(); if(!simple) { if( !symStack->VarAt(_text) ) throw SemanticException(currentToken, "Undeclared identifier"); if( symStack->TypeAt(_text) ) throw SemanticException(currentToken, "Using type as identifier"); } return new NodeVar(_text); } if(currentToken->GetTokenType() == CONST_INTEGER || currentToken->GetTokenType() == CONST_REAL || currentToken->GetTokenType() == CONST_CHAR || currentToken->GetTokenType() == CONST_STRING) { string id = GetRandomId("const_"); if(currentToken->GetTokenType() == CONST_CHAR || currentToken->GetTokenType() == CONST_STRING) { symStack->GetTopTable()->AddConst(new SymConst(id, text)); } Next(); return new NodeConst(id, lastToken->GetText()); } Node *expr = NULL; if(oper == ROUND_LEFT_BRACKET) { Next(); expr = Expression(); if(expr == NULL) throw ParserException(currentToken, "Expression expected"); if(oper == ROUND_RIGHT_BRACKET) { Next(); return expr; } return expr; } return NULL; }
Tipo* Negacion::validarSemantico() { Tipo* t_expr = expr->validarSemantico(); if ( t_expr->GetTipo() != t_boolean ) throw SemanticException("El operador de negacion es aplicable a tipo booleano"); return t_expr; }
void SymbolTreeBuilder::visit(AssignOperatorNode& node) { node.setScope(currentScope()); node.expressionLeft()->accept(*this); ExpressionResult left_exp_result = _expResult; if (!left_exp_result.symbol || (left_exp_result.symbol && !left_exp_result.symbol->isAssignable())) { throw SemanticException("Expression is not assignable", node); } node.expressionRight()->accept(*this); // validate types if (!_expResult.type->isPromotableTo(left_exp_result.type)) { std::stringstream stream; stream <<"Cannot convert right expression to left, expression type " << _expResult.type->typeString() <<" cannot be cast to " << left_exp_result.type->typeString() << std::endl; throw SemanticException(stream.str(), node); } _expResult.symbol->markAssigned(); if (node.assignOperatorType() == kOperatorTypeCopy && !left_exp_result.type->isObjectType() && left_exp_result.symbol->isTemporary()) { _curStatment->removeSymbolFromScope(_expResult.symbol); _curScope->eraseSymbol(_expResult.symbol); node.expressionRight()->setExpressionResult(ExpressionResult(_expResult.type, left_exp_result.symbol)); } node.setNodeType(left_exp_result.type); node.setExpressionResult(left_exp_result); left_exp_result.symbol->touchWrite(); }
Tipo* AndBinario::validarSemantico() { Tipo* t_op1 = op1->validarSemantico(); Tipo* t_op2 = op2->validarSemantico(); if ( t_op1->GetTipo() != t_boolean || t_op2->GetTipo() != t_boolean) throw SemanticException("El operador And solo es aplicable a tipo booleano"); return t_op1; }
Tipo* SumaUnaria::validarSemantico() { Tipo* t = InformacionSemantica::GetInstance()->GetTablaTipos().find("INTEGER")->second; Tipo* t_expr = expr->validarSemantico(); if ( !(t->EsEquivalente (t_expr )) ) throw SemanticException("Operador unario suma no es aplicable para este tipo"); return t_expr; }
void SentenciaCase::validarSemantica() { Tipo* t_evaluacion = evaluacion->validarSemantico(); if ( t_evaluacion->GetTipo() != t_entero && t_evaluacion->GetTipo() != t_caracter ) throw SemanticException("Solo se permite expresiones tipo entero o caracter para la evaluacion del case"); list<ClausulaCase*>::iterator it = clausulas.begin(); for ( ; it != clausulas.end() ; it++) { ClausulaCase* clausula = (*it); clausula->GetCodigo()->validacionSemantica(); Tipo* t_clausula = clausula->GetConstante()->validarSemantico(); if ( t_clausula->GetTipo() != t_evaluacion->GetTipo() ) throw SemanticException("El tipo de la clausula debe coincidir con el de la expresion que se evalua"); } if ( sentencia_defecto != 0 ) sentencia_defecto->validacionSemantica(); }
::Value* EqualNode::Interpret() { Value* leftNode = LeftNode->Interpret(); Value* righNode = RightNode->Interpret(); BooleanoValue * b; if (leftNode->Name.compare("Entero") == 0 && righNode->Name.compare("Entero") == 0) { int l = (dynamic_cast<EnteroValue*>(leftNode))->value; int r = (dynamic_cast<EnteroValue*>(righNode))->value; b = new BooleanoValue(l==r); return b; } else if (leftNode->Name.compare("Entero") == 0 && righNode->Name.compare("Real") == 0) { int l = (dynamic_cast<EnteroValue*>(leftNode))->value; float r = (dynamic_cast<RealValue*>(righNode))->value; b = new BooleanoValue(l == r); return b; } else if (leftNode->Name.compare("Real") == 0 && righNode->Name.compare("Entero") == 0) { float l = (dynamic_cast<RealValue*>(leftNode))->value; int r = (dynamic_cast<EnteroValue*>(righNode))->value; b = new BooleanoValue(l == r); return b; } else if (leftNode->Name.compare("Caracter") == 0 && righNode->Name.compare("Caracter") == 0) { char l = (dynamic_cast<CaracterValue*>(leftNode))->value; char r = (dynamic_cast<CaracterValue*>(righNode))->value; b = new BooleanoValue(l == r); return b; } else if (leftNode->Name.compare("Cadena") == 0 && righNode->Name.compare("Cadena") == 0) { string l = (dynamic_cast<CadenaValue*>(leftNode))->value; string r = (dynamic_cast<CadenaValue*>(righNode))->value; b = new BooleanoValue(l == r); return b; } else if (leftNode->Name.compare("Booleano") == 0 && righNode->Name.compare("Booleano") == 0) { bool l = (dynamic_cast<BooleanoValue*>(leftNode))->value; bool r = (dynamic_cast<BooleanoValue*>(righNode))->value; b = new BooleanoValue(l == r); return b; } else { throw SemanticException("Tipos de dato incompatibles " + leftNode->Name + "-" + righNode->Name + ",Fila:" + to_string(Row) + ",Columna:" + to_string(Column)); } }
void SymbolTreeBuilder::visit(FunctionCallArgsNode& node) { YAL_ASSERT(_curFunctionCall); node.setScope(currentScope()); FunctionType* func_type = cast_type<FunctionType>(_curFunctionCall->symbolType()); YAL_ASSERT(func_type); const yal_u32 nargs = func_type->argumentCount(); if (nargs != node.expressions.size()) { std::stringstream stream; stream <<"Function '" <<_curFunctionCall->symbolName() << "' expects"<< nargs << "arguments, you have provided " << node.expressions.size() << std::endl; throw SemanticException(stream.str(), node); } yal_u32 idx = 0; for(auto& v : node.expressions) { v->accept(*this); const Type* arg_type = func_type->typeOfArgument(idx); if (!_expResult.type->isPromotableTo(arg_type)) { std::stringstream stream; stream <<"Function '" <<_curFunctionCall->symbolName() << "' argument "<< idx << "expects type '" << arg_type->typeString() << "', but you have provided type '" << _expResult.type->typeString() << "'" << std::endl; throw SemanticException(stream.str(), node); } ++idx; } }
void StatementMientrasNode::ValidateSemantic() { if(Expression->ValidateSemantic()->Name!="Booleano") { throw SemanticException("Se esperaba Booleano ,Fila:"+to_string(Expression->Row)+",Columna:"+to_string(Expression->Column)); } list<StatementNode*>::const_iterator iterator; StatementNode* temp; for (iterator = Statements->begin(); iterator != Statements->end(); ++iterator) { temp=*iterator; temp->ValidateSemantic(); } }
void StatementParaNode::ValidateSemantic() { if(Variable->ValidateSemantic()->Name!="Entero") { throw SemanticException("Se esperaba Entero ,Fila:"+to_string(Variable->Row)+",Columna:"+to_string(Variable->Column)); } if(FirstExpression->ValidateSemantic()->Name!="Entero") { throw SemanticException("Se esperaba Entero ,Fila:"+to_string(FirstExpression->Row)+",Columna:"+to_string(FirstExpression->Column)); } if(SecondExpression->ValidateSemantic()->Name!="Entero") { throw SemanticException("Se esperaba Entero ,Fila:"+to_string(SecondExpression->Row)+",Columna:"+to_string(SecondExpression->Column)); } list<StatementNode*>::const_iterator iterator; StatementNode* temp; for (iterator = Statements->begin(); iterator != Statements->end(); ++iterator) { temp=*iterator; temp->ValidateSemantic(); } }
Type *ModNode::ValidateSemantic() { Type* leftNode=LeftNode->ValidateSemantic(); Type* righNode=RightNode->ValidateSemantic(); if(leftNode->Name.compare("Entero")==0 && righNode->Name.compare("Entero")==0) { return leftNode; }else { throw SemanticException("Se esperaba tipo de dato entero "+ leftNode->Name+"-"+righNode->Name+",Fila:"+to_string(Row)+",Columna:"+to_string(Column)); } }
void SymbolTreeBuilder::visit(SingleOperatorNode& node) { node.setScope(currentScope()); node.expression()->accept(*this); const OperatorType op_type = node.singleOperatorType(); const bool requires_signed_int = OperatorRequiresSignedType(op_type); const bool requires_integer = OperatorRequiresInteger(op_type); if (requires_signed_int && !_expResult.type->isSignedType()) { std::stringstream stream; stream << "Operator '" << OperatorTypeToStr(node.singleOperatorType()) << "' requires that right expression has a signed type" << std::endl; throw SemanticException(stream.str(), node); } if (requires_integer && !_expResult.type->isInteger()) { std::stringstream stream; stream << "Operator '" << OperatorTypeToStr(node.singleOperatorType()) << "' requires that right expression has an integer result" << std::endl; throw SemanticException(stream.str(), node); } Symbol* tmp_sym = _curScope->declareTemporarySymbol(_expResult.type, _expResult.type->isObjectType() ? Symbol::kFlagNewObject : 0); _curStatment->addSymbolToScope(tmp_sym); _expResult = ExpressionResult(_expResult.type, tmp_sym); node.setNodeType(_expResult.type); node.setExpressionResult(_expResult); }
void SymbolTreeBuilder::visit(FunctionDeclNode& node) { visit(static_cast<FunctionDeclBaseNode&>(node)); const char* func_name = node.functionNameWithType(); // declare func FunctionType* type = _typeRegistry.registerFunction(&node); if (!type) { std::stringstream stream; stream << "Failed to register '" << func_name << "'" << std::endl; throw SemanticException(stream.str(), node); } _curFunctionDecl = _curScope->declareSymbol(func_name, type, 0); YAL_ASSERT(_curFunctionDecl); // begin new scope beginScope(); // check for object type if (node.isObjectFunction()) { Type* object_type = node.objectType(); Symbol* self_sym = _curScope->declareSymbol("self", object_type, (!object_type->isObjectType() ? Symbol::kFlagReference : 0)| Symbol::kFlagAssignable | Symbol::kFlagVariable); (void) self_sym; YAL_ASSERT(self_sym); } node.functionArguments()->accept(*this); node.functionCode()->accept(*this); // register function in module YAL_ASSERT(_parserState->module.function(func_name) == nullptr); _parserState->module.addFunction(new ModuleFunction(_curFunctionDecl, &node)); // end scope endScope(); _curFunctionDecl = nullptr; }
Value* LogicalONode::Interpret() { Value* leftNode = LeftNode->Interpret(); Value* righNode = RightNode->Interpret(); BooleanoValue * b; if (leftNode->Name.compare("Booleano") == 0 && righNode->Name.compare("Booleano") == 0) { bool l = (dynamic_cast<BooleanoValue*>(leftNode))->value; bool r = (dynamic_cast<BooleanoValue*>(righNode))->value; b = new BooleanoValue(l || r); return b; } else { throw SemanticException("Tipos de dato incompatibles " + leftNode->Name + "-" + righNode->Name + ",Fila:" + to_string(Row) + ",Columna:" + to_string(Column)); } }
::Value* IntegerDivisionNode::Interpret() { Value* leftNode = LeftNode->Interpret(); Value* righNode = RightNode->Interpret(); EnteroValue * b; if (leftNode->Name.compare("Entero") == 0 && righNode->Name.compare("Entero") == 0) { int l = (dynamic_cast<EnteroValue*>(leftNode))->value; int r = (dynamic_cast<EnteroValue*>(righNode))->value; b = new EnteroValue(l / r); return b; } else { throw SemanticException("Tipos de dato incompatibles " + leftNode->Name + "-" + righNode->Name + ",Fila:" + to_string(Row) + ",Columna:" + to_string(Column)); } }