| /* |
| Copyright 2019 Alain Dargelas |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| /* |
| * File: CompileHelper.cpp |
| * Author: alain |
| * |
| * Created on May 14, 2019, 8:03 PM |
| */ |
| |
| #include "../Expression/Value.h" |
| #include "../Expression/ExprBuilder.h" |
| #include "../Design/Enum.h" |
| #include "../Design/Function.h" |
| #include "../Testbench/Property.h" |
| #include "../SourceCompile/CompilationUnit.h" |
| #include "../SourceCompile/PreprocessFile.h" |
| #include "../SourceCompile/CompileSourceFile.h" |
| #include "../SourceCompile/ParseFile.h" |
| #include "../SourceCompile/Compiler.h" |
| #include "../Design/Design.h" |
| #include "CompileHelper.h" |
| #include <iostream> |
| using namespace SURELOG; |
| |
| |
| CompileHelper::~CompileHelper () { } |
| |
| bool CompileHelper::importPackage(DesignComponent* scope, Design* design, FileContent* fC, NodeId id) |
| { |
| FileCNodeId fnid (fC, id); |
| scope->addObject (VObjectType::slPackage_import_item, fnid); |
| |
| NodeId nameId = fC->Child (id); |
| std::string pack_name = fC->SymName (nameId); |
| Package* def = design->getPackage (pack_name); |
| if (def) |
| { |
| scope->addAccessPackage (def); |
| auto& classSet = def->getObjects (VObjectType::slClass_declaration); |
| for (unsigned int i = 0; i < classSet.size (); i++) |
| { |
| FileContent* packageFile = classSet[i].fC; |
| NodeId classDef = classSet[i].nodeId; |
| std::string name = packageFile->SymName (classDef); |
| std::string fullName = def->getName () + "::" + name; |
| DesignComponent* comp = packageFile->getComponentDefinition (fullName); |
| FileCNodeId fnid (packageFile, classDef); |
| scope->addNamedObject (name, fnid, comp); |
| } |
| |
| auto& typeSet = def->getDataTypeMap (); |
| for (auto& type : typeSet) |
| { |
| scope->insertDataType (type.first, type.second); |
| } |
| |
| auto& variableSet = def->getVariables (); |
| for (auto& var : variableSet) |
| { |
| scope->addVariable (var.second); |
| Value* val = def->getValue (var.first); |
| if (val) |
| { |
| scope->setValue (var.first, val, *def->getExprBuilder()); |
| } |
| } |
| |
| } |
| else |
| { |
| Location loc (m_symbols->registerSymbol (fC->getFileName (id)), fC->Line (id), 0, m_symbols->registerSymbol (pack_name)); |
| Error err (ErrorDefinition::COMP_UNDEFINED_PACKAGE, loc); |
| m_errors->addError (err); |
| } |
| |
| return true; |
| } |
| |
| |
| bool CompileHelper::compileTfPortList(Procedure* parent, FileContent* fC, NodeId tf_port_list, TfPortList& targetList) { |
| bool result = true; |
| /* |
| n<c1> u<7> t<StringConst> p<29> s<27> l<10> |
| n<> u<8> t<IntegerAtomType_Int> p<9> l<12> |
| n<> u<9> t<Data_type> p<10> c<8> l<12> |
| n<> u<10> t<Function_data_type> p<11> c<9> l<12> |
| n<> u<11> t<Function_data_type_or_implicit> p<24> c<10> s<12> l<12> |
| n<try_get> u<12> t<StringConst> p<24> s<22> l<12> |
| n<> u<13> t<IntegerAtomType_Int> p<14> l<12> |
| n<> u<14> t<Data_type> p<15> c<13> l<12> |
| n<> u<15> t<Data_type_or_implicit> p<21> c<14> s<16> l<12> |
| n<keyCount> u<16> t<StringConst> p<21> s<20> l<12> |
| n<1> u<17> t<IntConst> p<18> l<12> |
| n<> u<18> t<Primary_literal> p<19> c<17> l<12> |
| n<> u<19> t<Primary> p<20> c<18> l<12> |
| n<> u<20> t<Expression> p<21> c<19> l<12> |
| n<> u<21> t<Tf_port_item> p<22> c<15> l<12> |
| n<> u<22> t<Tf_port_list> p<24> c<21> s<23> l<12> |
| n<> u<23> t<Endfunction> p<24> l<13> |
| n<> u<24> t<Function_body_declaration> p<25> c<11> l<12> |
| n<> u<25> t<Function_declaration> p<26> c<24> l<12> |
| n<> u<26> t<Class_method> p<27> c<25> l<12> |
| */ |
| /* |
| Or |
| n<get> u<47> t<StringConst> p<55> s<53> l<18> |
| n<> u<48> t<PortDir_Ref> p<49> l<18> |
| n<> u<49> t<Tf_port_direction> p<52> c<48> s<50> l<18> |
| n<> u<50> t<Data_type_or_implicit> p<52> s<51> l<18> |
| n<message> u<51> t<StringConst> p<52> l<18> |
| n<> u<52> t<Tf_port_item> p<53> c<49> l<18> |
| */ |
| // Compile arguments |
| if (tf_port_list && (fC->Type(tf_port_list) == VObjectType::slTf_port_list)) |
| { |
| NodeId tf_port_item = fC->Child(tf_port_list); |
| while (tf_port_item) |
| { |
| Value* value = NULL; |
| NodeId tf_data_type_or_implicit = fC->Child(tf_port_item); |
| NodeId tf_data_type = fC->Child(tf_data_type_or_implicit); |
| VObjectType tf_port_direction_type = fC->Type(tf_data_type_or_implicit); |
| NodeId tf_param_name = fC->Sibling(tf_data_type_or_implicit); |
| if (tf_port_direction_type == VObjectType::slTfPortDir_Ref || |
| tf_port_direction_type == VObjectType::slTfPortDir_ConstRef || |
| tf_port_direction_type == VObjectType::slTfPortDir_Inp || |
| tf_port_direction_type == VObjectType::slTfPortDir_Out || |
| tf_port_direction_type == VObjectType::slTfPortDir_Inout) |
| { |
| tf_data_type = fC->Sibling(tf_data_type_or_implicit); |
| tf_param_name = fC->Sibling(tf_data_type); |
| } |
| else |
| { |
| tf_port_direction_type = VObjectType::slNull_rule; |
| } |
| NodeId type = fC->Child(tf_data_type); |
| VObjectType the_type = fC->Type(type); |
| std::string typeName; |
| if (the_type == VObjectType::slStringConst) |
| { |
| typeName = fC->SymName (type); |
| } |
| else if (the_type == VObjectType::slClass_scope) |
| { |
| NodeId class_type = fC->Child (type); |
| NodeId class_name = fC->Child (class_type); |
| typeName = fC->SymName (class_name); |
| typeName += "::"; |
| NodeId symb_id = fC->Sibling(type); |
| typeName += fC->SymName (symb_id); |
| } |
| else |
| { |
| typeName = VObject::getTypeName (the_type); |
| } |
| std::string name = fC->SymName(tf_param_name); |
| NodeId expression = fC->Sibling(tf_param_name); |
| DataType* dtype = new DataType(fC, type, typeName, fC->Type(type)); |
| |
| if (expression && (fC->Type(expression) != VObjectType::slVariable_dimension) |
| && (dtype->getType() != VObjectType::slStringConst) ) |
| { |
| value = m_exprBuilder.evalExpr (fC, expression, parent->getParent ()); |
| } |
| NodeId range = 0; |
| TfPortItem* param = new TfPortItem(parent, fC, tf_port_item, range, name, dtype, value, tf_port_direction_type); |
| targetList.push_back(param); |
| tf_port_item = fC->Sibling(tf_port_item); |
| } |
| } |
| return result; |
| } |
| |
| DataType* |
| CompileHelper::compileTypeDef (DesignComponent* scope, FileContent* fC, NodeId data_declaration) |
| { |
| DataType* newType = NULL; |
| /* |
| n<> u<1> t<IntVec_TypeBit> p<12> s<11> l<5> |
| n<1> u<2> t<IntConst> p<3> l<5> |
| n<> u<3> t<Primary_literal> p<4> c<2> l<5> |
| n<> u<4> t<Constant_primary> p<5> c<3> l<5> |
| n<> u<5> t<Constant_expression> p<10> c<4> s<9> l<5> |
| n<0> u<6> t<IntConst> p<7> l<5> |
| n<> u<7> t<Primary_literal> p<8> c<6> l<5> |
| n<> u<8> t<Constant_primary> p<9> c<7> l<5> |
| n<> u<9> t<Constant_expression> p<10> c<8> l<5> |
| n<> u<10> t<Constant_range> p<11> c<5> l<5> |
| n<> u<11> t<Packed_dimension> p<12> c<10> l<5> |
| n<> u<12> t<Enum_base_type> p<21> c<1> s<14> l<5> |
| n<UVM_INFO> u<13> t<StringConst> p<14> l<7> |
| n<> u<14> t<Enum_name_declaration> p<21> c<13> s<16> l<7> |
| n<UVM_WARNING> u<15> t<StringConst> p<16> l<8> |
| n<> u<16> t<Enum_name_declaration> p<21> c<15> s<18> l<8> |
| n<UVM_ERROR> u<17> t<StringConst> p<18> l<9> |
| n<> u<18> t<Enum_name_declaration> p<21> c<17> s<20> l<9> |
| n<UVM_FATAL> u<19> t<StringConst> p<20> l<10> |
| n<> u<20> t<Enum_name_declaration> p<21> c<19> l<10> |
| n<> u<21> t<Data_type> p<23> c<12> s<22> l<5> |
| n<uvm_severity> u<22> t<StringConst> p<23> l<11> |
| n<> u<23> t<Type_declaration> p<24> c<21> l<5> |
| n<> u<24> t<Data_declaration> p<25> c<23> l<5> |
| */ |
| |
| NodeId type_declaration = fC->Child (data_declaration); |
| NodeId data_type = fC->Child (type_declaration); |
| |
| VObjectType dtype = fC->Type(data_type); |
| |
| |
| if ( dtype == VObjectType::slClass_keyword |
| || dtype == VObjectType::slStruct_keyword |
| || dtype == VObjectType::slUnion_keyword |
| || dtype == VObjectType::slInterface_class_keyword |
| || dtype == VObjectType::slEnum_keyword) |
| { |
| NodeId type_name = fC->Sibling (data_type); |
| std::string name = fC->SymName (type_name); |
| TypeDef* prevDef = scope->getTypeDef (name); |
| if (prevDef) |
| return prevDef; |
| NodeId stype = fC->Sibling (data_type); |
| if (fC->Type (stype) == VObjectType::slStringConst) |
| { |
| TypeDef* newTypeDef = new TypeDef (fC, type_declaration, stype, name); |
| scope->insertTypeDef (newTypeDef); |
| newType = newTypeDef; |
| return newType; |
| } |
| } |
| |
| |
| if (dtype != VObjectType::slData_type) |
| { |
| return NULL; |
| } |
| |
| NodeId type_name = fC->Sibling (data_type); |
| std::string name = fC->SymName (type_name); |
| TypeDef* prevDef = scope->getTypeDef (name); |
| if (prevDef) |
| { |
| Location loc1 (m_symbols->registerSymbol (fC->getFileName (data_type)), fC->Line (data_type), 0, m_symbols->registerSymbol (name)); |
| FileContent* prevFile = prevDef->getFileContent (); |
| NodeId prevNode = prevDef->getNodeId (); |
| Location loc2 (m_symbols->registerSymbol (prevFile->getFileName (prevNode)), prevFile->Line (prevNode), 0, m_symbols->registerSymbol (name)); |
| Error err (ErrorDefinition::COMP_MULTIPLY_DEFINED_TYPEDEF, loc1, loc2); |
| m_errors->addError (err); |
| } |
| |
| VObjectType base_type = fC->Type (data_type); |
| |
| DataType* type = new DataType (fC, data_type, name, base_type); |
| scope->insertDataType (name, type); |
| |
| // Enum or Struct or Union |
| NodeId enum_base_type = fC->Child (data_type); |
| bool enumType = false; |
| bool structType = false; |
| NodeId enum_base_type_node = VObjectType::slNull_rule; |
| VObjectType enum_base_type_type = VObjectType::slNull_rule; |
| NodeId enum_name_declaration = VObjectType::slNull_rule; |
| if (fC->Type (enum_base_type) == VObjectType::slEnum_base_type) |
| { |
| enum_base_type_node = fC->Child (enum_base_type); |
| enum_base_type_type = fC->Type (enum_base_type_node); |
| enum_name_declaration = fC->Sibling (enum_base_type); |
| enumType = true; |
| } |
| else if (fC->Type (enum_base_type) == VObjectType::slEnum_name_declaration) |
| { |
| enumType = true; |
| enum_name_declaration = enum_base_type; |
| enum_base_type = 0; |
| enum_base_type_type = VObjectType::slIntegerAtomType_Byte; |
| } |
| else if (fC->Type (enum_base_type) == VObjectType::slStruct_union) |
| { |
| structType = true; |
| //NodeId struct_or_union = fC->Child(enum_base_type); |
| //VObjectType struct_or_union_type = fC->Type(struct_or_union); |
| NodeId struct_or_union_member = fC->Sibling(enum_base_type); |
| while (struct_or_union_member) |
| { |
| |
| struct_or_union_member = fC->Sibling(struct_or_union_member); |
| } |
| TypeDef* newTypeDef = new TypeDef (fC, type_declaration, type_name, name); |
| scope->insertTypeDef (newTypeDef); |
| } |
| if (enumType) |
| { |
| TypeDef* newTypeDef = new TypeDef (fC, type_declaration, enum_base_type, name); |
| int val = 0; |
| Enum* the_enum = new Enum (name, fC, enum_base_type, enum_base_type_type); |
| newTypeDef->setEnum (the_enum); |
| newTypeDef->setDefinition (the_enum); |
| newType = newTypeDef; |
| while (enum_name_declaration) |
| { |
| NodeId enumNameId = fC->Child (enum_name_declaration); |
| std::string enumName = fC->SymName (enumNameId); |
| NodeId enumValueId = fC->Sibling (enumNameId); |
| Value* value = NULL; |
| if (enumValueId) |
| { |
| value = m_exprBuilder.evalExpr (fC, enumValueId, NULL); |
| } |
| else |
| { |
| value = m_exprBuilder.getValueFactory ().newLValue (); |
| value->set (val, Value::Integer, 32); |
| } |
| the_enum->addValue (enumName, value); |
| enum_name_declaration = fC->Sibling (enum_name_declaration); |
| val++; |
| scope->setValue (enumName, value, m_exprBuilder); |
| Variable* variable = new Variable (type, fC, enumValueId, 0, enumName); |
| scope->addVariable (variable); |
| } |
| |
| type->setDefinition (newTypeDef); |
| scope->insertTypeDef (newTypeDef); |
| |
| } |
| else if (structType) |
| { |
| |
| } |
| else |
| { |
| NodeId stype = fC->Child (data_type); |
| if (fC->Type (stype) == VObjectType::slStringConst) |
| { |
| TypeDef* newTypeDef = new TypeDef (fC, type_declaration, stype, name); |
| type->setDefinition (newTypeDef); |
| scope->insertTypeDef (newTypeDef); |
| newType = newTypeDef; |
| } |
| } |
| |
| return newType; |
| } |
| |
| bool CompileHelper::compileScopeBody(Scope* parent, Statement* parentStmt, FileContent* fC, NodeId function_statement_or_null) { |
| bool result = true; |
| while (function_statement_or_null) |
| { |
| VObjectType nodeType = fC->Type (function_statement_or_null); |
| switch (nodeType) |
| { |
| case VObjectType::slFunction_statement_or_null: |
| case VObjectType::slStatement_or_null: |
| { |
| NodeId statement = fC->Child (function_statement_or_null); |
| NodeId statement_item = fC->Child (statement); |
| NodeId item = fC->Child (statement_item); |
| VObjectType stmtType = fC->Type (item); |
| switch (stmtType) |
| { |
| case VObjectType::slSubroutine_call_statement: |
| { |
| compileSubroutine_call(parent, parentStmt, fC, item); |
| break; |
| } |
| case VObjectType::slSeq_block: |
| compileSeqBlock_stmt(parent,parentStmt, fC, item); |
| break; |
| case VObjectType::slLoop_statement: |
| compileLoop_stmt(parent, parentStmt, fC, item); |
| break; |
| default: // stmtType |
| break; |
| } |
| break; |
| } |
| case VObjectType::slStatement: |
| { |
| NodeId statement = function_statement_or_null; |
| NodeId statement_item = fC->Child (statement); |
| NodeId item = fC->Child (statement_item); |
| VObjectType stmtType = fC->Type (item); |
| switch (stmtType) |
| { |
| case VObjectType::slSubroutine_call_statement: |
| { |
| compileSubroutine_call(parent, parentStmt, fC, item); |
| break; |
| } |
| case VObjectType::slSeq_block: |
| compileSeqBlock_stmt(parent,parentStmt, fC, item); |
| break; |
| case VObjectType::slLoop_statement: |
| compileLoop_stmt(parent, parentStmt, fC, item); |
| break; |
| default: // stmtType |
| break; |
| } |
| break; |
| } |
| break; |
| case VObjectType::slBlock_item_declaration: |
| compileScopeVariable (parent, fC, function_statement_or_null); |
| break; |
| case VObjectType::slSuper_dot_new: |
| { |
| NodeId list_of_arguments = fC->Sibling (function_statement_or_null); |
| NodeId expression = fC->Child (list_of_arguments); |
| std::vector<SubRoutineArg*> args; |
| while (expression) |
| { |
| SubRoutineArg* arg = new SubRoutineArg (expression, NULL); |
| args.push_back (arg); |
| expression = fC->Sibling (expression); |
| } |
| std::vector<NodeId> var_chain; |
| var_chain.push_back(function_statement_or_null); |
| SubRoutineCallStmt* stmt = new SubRoutineCallStmt (parent, parentStmt, fC, function_statement_or_null, VObjectType::slSubroutine_call_statement, |
| var_chain, "new", args, false, false); |
| parent->addStmt (stmt); |
| if (parentStmt) |
| parentStmt->addStatement (stmt); |
| break; |
| } |
| default: |
| break; |
| } |
| function_statement_or_null = fC->Sibling (function_statement_or_null); |
| } |
| |
| return result; |
| } |
| |
| |
| bool CompileHelper::compileSubroutine_call(Scope* parent, Statement* parentStmt, FileContent* fC, NodeId subroutine_call_statement) |
| { |
| /* |
| n<d> u<44> t<StringConst> p<48> s<45> l<15> |
| n<> u<45> t<Constant_bit_select> p<48> s<46> l<15> |
| n<get_current_item> u<46> t<StringConst> p<48> s<47> l<15> |
| n<> u<47> t<List_of_arguments> p<48> l<15> |
| n<> u<48> t<Subroutine_call> p<49> c<44> l<15> |
| n<> u<49> t<Subroutine_call_statement> p<50> c<48> l<15> |
| n<> u<50> t<Statement_item> p<51> c<49> l<15> |
| n<> u<51> t<Statement> p<52> c<50> l<15> |
| n<> u<52> t<Function_statement_or_null> p<61> c<51> s<59> l<15> |
| n<foo> u<53> t<StringConst> p<55> s<54> l<16> |
| n<> u<54> t<List_of_arguments> p<55> l<16> |
| n<> u<55> t<Subroutine_call> p<56> c<53> l<16> |
| n<> u<56> t<Subroutine_call_statement> p<57> c<55> l<16> |
| n<> u<57> t<Statement_item> p<58> c<56> l<16> |
| n<> u<58> t<Statement> p<59> c<57> l<16> |
| n<> u<59> t<Function_statement_or_null> p<61> c<58> s<60> l<16> |
| */ |
| std::vector<NodeId> var_chain; |
| NodeId subroutine_call = fC->Child (subroutine_call_statement); |
| NodeId base_name = fC->Child (subroutine_call); |
| NodeId next_name = base_name; |
| bool static_call = false; |
| bool system_call = false; |
| if (fC->Type (base_name) == VObjectType::slDollar_keyword) |
| { |
| // system calls |
| base_name = fC->Sibling (base_name); |
| next_name = base_name; |
| system_call = true; |
| } |
| else if (fC->Type (base_name) == VObjectType::slImplicit_class_handle) |
| { |
| next_name = fC->Sibling (base_name); |
| base_name = fC->Child (base_name); |
| var_chain.push_back (base_name); |
| } |
| else if (fC->Type (base_name) == VObjectType::slClass_scope) |
| { |
| next_name = fC->Sibling (base_name); |
| base_name = fC->Child (base_name); |
| base_name = fC->Child (base_name); |
| while (base_name) |
| { |
| VObjectType ntype = fC->Type (base_name); |
| if (ntype == VObjectType::slParameter_value_assignment) |
| { |
| base_name = fC->Sibling (base_name); |
| } |
| if (base_name == 0) |
| break; |
| var_chain.push_back (base_name); |
| base_name = fC->Sibling (base_name); |
| } |
| static_call = true; |
| } |
| while (next_name) |
| { |
| VObjectType ntype = fC->Type (next_name); |
| if (ntype == VObjectType::slConstant_bit_select) |
| { |
| next_name = fC->Sibling (next_name); |
| } |
| if (ntype == VObjectType::slSelect) |
| { |
| next_name = fC->Sibling (next_name); |
| } |
| if (next_name == 0) |
| break; |
| if (ntype == VObjectType::slList_of_arguments) |
| { |
| break; |
| } |
| var_chain.push_back (next_name); |
| |
| next_name = fC->Sibling (next_name); |
| } |
| std::string funcName = fC->SymName (var_chain[var_chain.size () - 1]); |
| var_chain.pop_back (); |
| |
| NodeId list_of_arguments = next_name; |
| NodeId expression = fC->Child (list_of_arguments); |
| std::vector<SubRoutineArg*> args; |
| while (expression) |
| { |
| SubRoutineArg* arg = new SubRoutineArg (expression, NULL); |
| args.push_back (arg); |
| expression = fC->Sibling (expression); |
| } |
| |
| SubRoutineCallStmt* stmt = new SubRoutineCallStmt (parent, parentStmt, fC, subroutine_call, VObjectType::slSubroutine_call_statement, |
| var_chain, funcName, args, static_call, system_call); |
| parent->addStmt (stmt); |
| if (parentStmt) |
| parentStmt->addStatement (stmt); |
| return true; |
| } |
| |
| bool CompileHelper::compileSeqBlock_stmt(Scope* parent, Statement* parentStmt, FileContent* fC, NodeId seq_block) { |
| NodeId item = fC->Child(seq_block); |
| std::string name = ""; |
| SeqBlock* block = new SeqBlock(name, parent, parentStmt, fC, seq_block); |
| parent->addScope(block); |
| parent->addStmt (block); |
| if (parentStmt) |
| parentStmt->addStatement (block); |
| compileScopeBody(block, block, fC, item); |
| return true; |
| } |
| |
| bool CompileHelper::compileLoop_stmt(Scope* parent, Statement* parentStmt, FileContent* fC, NodeId loop_statement) |
| { |
| NodeId loop = fC->Child(loop_statement); |
| NodeId expression = fC->Sibling(loop); |
| switch (fC->Type(loop)) |
| { |
| case VObjectType::slFor_initialization: |
| case VObjectType::slExpression: |
| compileForLoop_stmt(parent, parentStmt, fC, loop); |
| break; |
| case VObjectType::slStatement_or_null: |
| if (expression) |
| { |
| // Do loop |
| } |
| else |
| compileForLoop_stmt(parent, parentStmt, fC, loop); |
| break; |
| case VObjectType::slPs_or_hierarchical_array_identifier: |
| compileForeachLoop_stmt(parent, parentStmt, fC, loop); |
| default: |
| break; |
| } |
| return true; |
| } |
| |
| bool CompileHelper::compileForeachLoop_stmt(Scope* parent, Statement* parentStmt, FileContent* fC, NodeId ps_or_hierarchical_array_identifier) { |
| NodeId loop_variables = fC->Sibling(ps_or_hierarchical_array_identifier); |
| NodeId statement = fC->Sibling(loop_variables); |
| ForeachLoopStmt* stmt = new ForeachLoopStmt("", fC->Child(ps_or_hierarchical_array_identifier), parent, parentStmt, fC, ps_or_hierarchical_array_identifier, VObjectType::slPs_or_hierarchical_array_identifier); |
| parent->addStmt (stmt); |
| parent->addScope(stmt); |
| loop_variables = fC->Child(loop_variables); |
| while (loop_variables) |
| { |
| stmt->addIteratorId (loop_variables); |
| loop_variables = fC->Sibling(loop_variables); |
| } |
| if (parentStmt) |
| parentStmt->addStatement (stmt); |
| compileScopeBody(parent, stmt, fC, statement); |
| |
| return true; |
| } |
| |
| |
| bool CompileHelper::compileForLoop_stmt(Scope* parent, Statement* parentStmt, FileContent* fC, NodeId first_node) { |
| VObjectType init_type = fC->Type(first_node); |
| NodeId for_initialization = 0; |
| NodeId expression = 0; |
| NodeId for_step = 0; |
| NodeId statement_or_null = 0; |
| NodeId itr_data_type = 0; |
| ForLoopStmt* stmt = NULL; |
| if (init_type == VObjectType::slStatement_or_null) |
| { |
| // for ( ; ; ) |
| statement_or_null = first_node; |
| stmt = new ForLoopStmt("", parent, parentStmt, fC, first_node, VObjectType::slStatement_or_null); |
| } |
| else if (init_type == VObjectType::slFor_initialization) |
| { |
| // for ( int i = 0; xxx ; xxx ) |
| for_initialization = first_node; |
| expression = fC->Sibling(for_initialization); |
| if (fC->Type(expression) == VObjectType::slExpression) |
| for_step = fC->Sibling(expression); |
| else |
| { |
| for_step = expression; |
| expression = 0; |
| } |
| if (fC->Type(for_step) == VObjectType::slFor_step) |
| statement_or_null = fC->Sibling(for_step); |
| else |
| { |
| statement_or_null = for_step; |
| for_step = 0; |
| } |
| stmt = new ForLoopStmt("", parent, parentStmt, fC, for_initialization, VObjectType::slFor_initialization); |
| NodeId for_variable_declaration = fC->Child (for_initialization); |
| if (for_variable_declaration) |
| itr_data_type = fC->Child (for_variable_declaration); |
| NodeId the_data_type = fC->Child (itr_data_type); |
| VObjectType the_type = fC->Type (the_data_type); |
| stmt->setIteratorType (the_type); |
| } |
| else if (init_type == VObjectType::slExpression) |
| { |
| // for ( ; i < 1 ; xxx ) |
| expression = first_node; |
| for_step = fC->Sibling(expression); |
| if (fC->Type(for_step) == VObjectType::slFor_step) |
| statement_or_null = fC->Sibling(for_step); |
| else |
| { |
| statement_or_null = for_step; |
| for_step = 0; |
| } |
| stmt = new ForLoopStmt("", parent, parentStmt, fC, first_node, VObjectType::slExpression); |
| } |
| parent->addStmt (stmt); |
| parent->addScope(stmt); |
| |
| if (expression != 0) |
| stmt->setConditionId (expression); |
| |
| if (itr_data_type) |
| { |
| NodeId iterator = fC->Sibling (itr_data_type); |
| while (iterator) |
| { |
| NodeId expression = fC->Sibling (iterator); |
| if (expression) |
| { |
| stmt->addIteratorId (iterator, expression); |
| iterator = fC->Sibling (expression); |
| } |
| else |
| { |
| stmt->addIteratorId (iterator, 0); |
| break; |
| } |
| } |
| } |
| |
| |
| if (for_step) |
| { |
| NodeId for_step_assignment = fC->Child (for_step); |
| while (for_step_assignment) |
| { |
| NodeId incr = fC->Child (for_step_assignment); |
| stmt->addIteratorStepId (incr); |
| for_step_assignment = fC->Sibling (for_step_assignment); |
| } |
| } |
| |
| if (parentStmt) |
| parentStmt->addStatement (stmt); |
| compileScopeBody(parent, stmt, fC, statement_or_null); |
| |
| return true; |
| } |
| |
| bool CompileHelper::compileScopeVariable (Scope* parent, FileContent* fC, NodeId id) { |
| NodeId data_declaration = fC->Child(id); |
| NodeId var_decl = fC->Child(data_declaration); |
| VObjectType type = fC->Type (data_declaration); |
| if (type == VObjectType::slData_declaration) |
| { |
| /* |
| n<A> u<3> t<StringConst> p<37> s<12> l<5> |
| n<> u<4> t<IntegerAtomType_Int> p<5> l<6> |
| n<> u<5> t<Data_type> p<9> c<4> s<8> l<6> |
| n<size> u<6> t<StringConst> p<7> l<6> |
| n<> u<7> t<Variable_decl_assignment> p<8> c<6> l<6> |
| n<> u<8> t<List_of_variable_decl_assignments> p<9> c<7> l<6> |
| n<> u<9> t<Variable_declaration> p<10> c<5> l<6> |
| n<> u<10> t<Data_declaration> p<11> c<9> l<6> |
| n<> u<11> t<Class_property> p<12> c<10> l<6> |
| n<> u<12> t<Class_item> p<37> c<11> s<35> l<6> |
| */ |
| VObjectType var_type = fC->Type (var_decl); |
| if (var_type == VObjectType::slVariable_declaration) |
| { |
| NodeId data_type = fC->Child (var_decl); |
| NodeId node_type = fC->Child (data_type); |
| VObjectType the_type = fC->Type (node_type); |
| std::string typeName; |
| if (the_type == VObjectType::slStringConst) |
| { |
| typeName = fC->SymName (node_type); |
| } |
| else if (the_type == VObjectType::slClass_scope) |
| { |
| NodeId class_type = fC->Child (node_type); |
| NodeId class_name = fC->Child (class_type); |
| typeName = fC->SymName (class_name); |
| typeName += "::"; |
| NodeId symb_id = fC->Sibling(node_type); |
| typeName += fC->SymName (symb_id); |
| } |
| else |
| { |
| typeName = VObject::getTypeName (the_type); |
| } |
| DataType* datatype = parent->getUsedDataType (typeName); |
| if (!datatype) |
| { |
| DataType* type = new DataType(fC, node_type, typeName, fC->Type(node_type)); |
| parent->insertUsedDataType (typeName, type); |
| datatype = parent->getUsedDataType (typeName); |
| } |
| |
| NodeId list_of_variable_decl_assignments = fC->Sibling (data_type); |
| NodeId variable_decl_assignment = fC->Child (list_of_variable_decl_assignments); |
| while (variable_decl_assignment) |
| { |
| NodeId var = fC->Child (variable_decl_assignment); |
| VObjectType varType = fC->Type(var); |
| NodeId range = fC->Sibling(var); |
| if (varType == VObjectType::slList_of_arguments) |
| { |
| // new () |
| } |
| else |
| { |
| std::string varName = fC->SymName (var); |
| |
| Variable* previous = parent->getVariable (varName); |
| if (previous) |
| { |
| Location loc1 (m_symbols->registerSymbol (fC->getFileName (var)), fC->Line (var), 0, m_symbols->registerSymbol (varName)); |
| FileContent* prevFile = previous->getFileContent (); |
| NodeId prevNode = previous->getNodeId (); |
| Location loc2 (m_symbols->registerSymbol (prevFile->getFileName (prevNode)), prevFile->Line (prevNode), 0, m_symbols->registerSymbol (varName)); |
| Error err (ErrorDefinition::COMP_MULTIPLY_DEFINED_VARIABLE, loc1, loc2); |
| m_errors->addError (err); |
| } |
| |
| Variable* variable = new Variable(datatype, fC, var, range, varName); |
| parent->addVariable (variable); |
| } |
| |
| variable_decl_assignment = fC->Sibling (variable_decl_assignment); |
| } |
| } |
| else if (var_type == VObjectType::slType_declaration) |
| { |
| // compile_type_declaration_(fC, var_decl); |
| } |
| } |
| |
| return true; |
| } |
| |
| Function* CompileHelper::compileFunctionPrototype(DesignComponent* scope, FileContent* fC, NodeId id) { |
| DataType* returnType = new DataType(); |
| std::string funcName; |
| /* |
| n<"DPI-C"> u<2> t<StringLiteral> p<15> s<3> l<3> |
| n<> u<3> t<Context_keyword> p<15> s<14> l<3> |
| n<> u<4> t<IntVec_TypeBit> p<5> l<3> |
| n<> u<5> t<Data_type> p<6> c<4> l<3> |
| n<> u<6> t<Function_data_type> p<14> c<5> s<7> l<3> |
| n<SV2C_peek> u<7> t<StringConst> p<14> s<13> l<3> |
| n<> u<8> t<IntegerAtomType_Int> p<9> l<3> |
| n<> u<9> t<Data_type> p<10> c<8> l<3> |
| n<> u<10> t<Data_type_or_implicit> p<12> c<9> s<11> l<3> |
| n<x_id> u<11> t<StringConst> p<12> l<3> |
| n<> u<12> t<Tf_port_item> p<13> c<10> l<3> |
| n<> u<13> t<Tf_port_list> p<14> c<12> l<3> |
| n<> u<14> t<Function_prototype> p<15> c<6> l<3> |
| n<> u<15> t<Dpi_import_export> p<16> c<2> l<3> |
| */ |
| VObjectType type = fC->Type(id); |
| |
| if (type == VObjectType::slDpi_import_export) |
| { |
| NodeId dpiType = fC->Child(id); |
| std::string stringtype; |
| // bool context = false; |
| // bool pure = false; |
| if (fC->Type(dpiType) == VObjectType::slStringLiteral) |
| { |
| stringtype = fC->SymName(dpiType); |
| } |
| NodeId prop = fC->Sibling(dpiType); |
| if (fC->Type(prop) == VObjectType::slContext_keyword) |
| { |
| //context = true; |
| prop = fC->Sibling(prop); |
| } |
| if (fC->Type(prop) == VObjectType::slPure_keyword) |
| { |
| //pure = true; |
| prop = fC->Sibling(prop); |
| } |
| NodeId func_prototype = prop; |
| NodeId function_data_type = fC->Child (func_prototype); |
| NodeId data_type = fC->Child (function_data_type); |
| NodeId type = fC->Child (data_type); |
| VObjectType the_type = fC->Type (type); |
| std::string typeName; |
| if (the_type == VObjectType::slStringConst) |
| { |
| typeName = fC->SymName (type); |
| } |
| else if (the_type == VObjectType::slClass_scope) |
| { |
| NodeId class_type = fC->Child (type); |
| NodeId class_name = fC->Child (class_type); |
| typeName = fC->SymName (class_name); |
| typeName += "::"; |
| NodeId symb_id = fC->Sibling (type); |
| typeName += fC->SymName (symb_id); |
| } |
| else |
| { |
| typeName = VObject::getTypeName (the_type); |
| } |
| returnType->init (fC, type, typeName, fC->Type (type)); |
| NodeId function_name = fC->Sibling (function_data_type); |
| funcName = fC->SymName (function_name); |
| |
| } |
| |
| Function* result = new Function(scope, fC, id, funcName, returnType); |
| Variable* variable = new Variable(returnType, fC, id, 0, funcName); |
| result->addVariable (variable); |
| result->compile (*this); |
| return result; |
| } |