blob: cf2b94ece815c5a2371cc906fc2cbfe3b367704c [file] [log] [blame]
/*
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 "DesignCompile/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::Type::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;
}