void CodeGenerator::ProcessVarTerm(int flags) { infunc(CodeGenerator::ProcessVarTerm); char name[MAX_LABEL_SIZE]; VarType type; if ((flags & FLAGS_IN_STATE) && !(flags & FLAGS_IN_FUNCTION)) throw CompileError("(Line %d) Not allowed variable declarations inside states, but outside of functions", CUR_TOKEN.line); // Grab the type GetTypeInfo(type, 0); // Loop until the declaration has ended while (CUR_TOKEN.type != TOKEN_END_OF_LINE) { Variable *var; if (CUR_TOKEN.type != TOKEN_NAME) throw CompileError("(Line %d) No name after type declaration", CUR_TOKEN.line); // Get the current variable name IsolateTokenString(CUR_TOKEN); strcpy(name, token_string); INC_TOKEN; // Grab the array dimensions if it's an array if (CUR_TOKEN.type == TOKEN_ARRAY_OPEN) GetArrayInfo(type); if (g_Object == NULL) { if (flags & FLAGS_IN_FUNCTION) { var = cur_class->cur_function->AddLocal(type, name); } else { // Create a new variable if ((var = new Variable) == NULL) throw CError("Couldn't allocate variable structure"); var->SetType(type); var->SetScope(VARIABLE_SCOPE_MEMBER); if (type.array) { var->SetAddress(cur_class->NewAddress(4 + (type.elements << 2), 0)); var->SetArrayElements(type.elements); } else var->SetAddress(cur_class->NewAddress(4, 1)); // Add it to the class list of variables cur_class->variables.Add(name, var); } } else { // Variable already defined, get it from the class var = cur_class->GetVariable(name, flags); // Check for invalid custom variable types if (var->GetType().id == VARIABLE_TYPEID_CUSTOM) if (g_Env->GetClass(var->GetType().name) == NULL) throw CompileError("(Line %d) Undefined variable type", CUR_TOKEN.line); // Local variables that are arrays need to be prepared if (flags & FLAGS_IN_FUNCTION && var->GetType().array) g_Object->WriteOp(OPCODE_ARRAYP, var->GetAddress()); } // Check for initial values if (CUR_TOKEN.type == TOKEN_ASSIGN) { if (type.id == VARIABLE_TYPEID_CUSTOM) throw CompileError("(Line %d) Not allowed immediate assignments on custom variable types", CUR_TOKEN.line); INC_TOKEN; // Is this an array? if (var->GetArrayElements()) { int x = 0, neg; dynamic num; neg = 0; if (CUR_TOKEN.type != TOKEN_BLOCK_OPEN) throw CompileError("(Line %d) Expecting block open for array default value definition", CUR_TOKEN.line); INC_TOKEN; while (1) { // Check for exit if (CUR_TOKEN.type == TOKEN_BLOCK_CLOSE) { INC_TOKEN; break; } // Check for too many variables if (x == var->GetArrayElements()) throw CompileError("(Line %d) Too many initialisers for array", CUR_TOKEN.line); // Read the value ReadConstant(&num, type, TOKEN_COMMA, TOKEN_BLOCK_CLOSE); if (g_Object == NULL) var->SetElementValue(x, &num); x++; // Check for the comma if (CUR_TOKEN.type != TOKEN_BLOCK_CLOSE) { if (CUR_TOKEN.type != TOKEN_COMMA) throw CompileError("(Line %d) Expecting comma seperator", CUR_TOKEN.line); INC_TOKEN; // Check for situations like = { 4, }; if (CUR_TOKEN.type == TOKEN_BLOCK_CLOSE) throw CompileError("(Line %d) Expecting array element", CUR_TOKEN.line); } } } // No else { dynamic num; ReadConstant(&num, type, TOKEN_END_OF_LINE, TOKEN_COMMA); if (g_Object == NULL) var->SetDefaultValue(&num); } } // Check for multiple variable declarations if (CUR_TOKEN.type == TOKEN_COMMA) { INC_TOKEN; if (CUR_TOKEN.type == TOKEN_END_OF_LINE) throw CompileError("(Line %d) Unexpected end of line", CUR_TOKEN.line); } else if (CUR_TOKEN.type != TOKEN_END_OF_LINE) throw CompileError("(Line %d) Illegal token after variable declaration", CUR_TOKEN.line); } outfunc; }
void CodeGenerator::ProcessFunctionTerm(int flags) { VarType ret_type; Function *func_ptr; int final = 0; infunc(CodeGenerator::ProcessFunctionTerm); INC_TOKEN; // Check for function modifiers switch (CUR_TOKEN.type) { // Final definition of this function within the hierarchy case (TOKEN_FINAL): ProcessFunctionTerm(flags | FLAGS_FUNCTION_FINAL); return; // This function is externally defined (C++) case (TOKEN_IMPORT): ProcessFunctionTerm(flags | FLAGS_FUNCTION_IMPORT); return; } // Does this specify a return type? if (CUR_TOKEN.Group() == TOKEN_GROUP_KEYWORD) { GetTypeInfo(ret_type, 0); // Check for invalid variable return types on the 2nd pass if (g_Object) if (ret_type.id == VARIABLE_TYPEID_CUSTOM) if (g_Env->GetClass(ret_type.name) == NULL) throw CompileError("(Line %d) Undefined variable type", CUR_TOKEN.type); // Process the array dimensions if it returns an array if (CUR_TOKEN.type == TOKEN_ARRAY_OPEN) { GetArrayInfo(ret_type); } } // No return specified, treat as void else if (CUR_TOKEN.type == TOKEN_NAME) { ret_type.Make(VARIABLE_TYPEID_VOID); } // Error else { throw CompileError("(Line %d) Illegal token after function declaration", CUR_TOKEN.line); } if (CUR_TOKEN.type != TOKEN_NAME) throw CompileError("(Line %d) No name found for function", CUR_TOKEN.line); // Grab the name IsolateTokenString(CUR_TOKEN); INC_TOKEN; if (CUR_TOKEN.type != TOKEN_LEFT_BRACKET) throw CompileError("(Line %d) No opening bracket found", CUR_TOKEN.line); // Move over the open bracket INC_TOKEN; if (g_Object == NULL) { // Create a new function if ((func_ptr = new Function) == NULL) throw CError("Couldn't allocate function structure"); // This is an imported function if (flags & FLAGS_FUNCTION_IMPORT) { // Add it to the imported list cur_class->imp_functions.Add(token_string, func_ptr); // Set function information func_ptr->SetIndex(cur_class->NewImportIndex()); func_ptr->SetFlag(FFLAGS_IMPORTED); func_ptr->SetReturnType(ret_type); } // This is a normal function else { // Add the function to its appropriate list if (flags & FLAGS_IN_STATE) cur_class->cur_state->functions.Add(token_string, func_ptr); else cur_class->functions.Add(token_string, func_ptr); // Set function information func_ptr->SetIndex(cur_class->NewFunctionIndex()); func_ptr->SetFlag((flags & FLAGS_FUNCTION_FINAL) ? FFLAGS_FINAL : 0); func_ptr->SetReturnType(ret_type); // Check to see if this is a constructor definition and set the entry point if (!strcmp(token_string, cur_class->GetName())) cur_class->SetEntryPoint(func_ptr->GetIndex()); } } else { // Imported function if (flags & FLAGS_FUNCTION_IMPORT) { // Function already defined, get it from within the class func_ptr = cur_class->GetImport(token_string); } // Normal function else { // Function already defined, get it from within the class func_ptr = cur_class->GetFunction(token_string, flags); // Safe to set the code location func_ptr->SetCodeLocation(g_Object->GetPosition()); // Enter stack frame if (func_ptr->GetCurAddress() || func_ptr->GetCurPAddress()) g_Object->WriteOp(OPCODE_INSTF); // Allocate some space on the stack if (func_ptr->GetCurAddress()) g_Object->WriteOp(OPCODE_SUBST, func_ptr->GetCurAddress()); } } while (1) { VarType type; Variable *var; // Check for no parameters if (CUR_TOKEN.type == TOKEN_VOID) { // void INC_TOKEN; if (func_ptr->GetNumParams()) throw CompileError("(Line %d) Illegal placement of void type", CUR_TOKEN.line); if (CUR_TOKEN.type != TOKEN_RIGHT_BRACKET) throw CompileError("(Line %d) Expecting closing bracket", CUR_TOKEN.line); // Closing bracket INC_TOKEN; break; } // That's when to end! if (CUR_TOKEN.type == TOKEN_RIGHT_BRACKET) { INC_TOKEN; break; } // Get the variable type GetTypeInfo(type, 0); // Check for invalid variable types on the 2nd pass if (g_Object && type.id == VARIABLE_TYPEID_CUSTOM) if (g_Env->GetClass(type.name) == NULL) throw CompileError("(Line %d) Undefined variable type", CUR_TOKEN.line); if (CUR_TOKEN.type != TOKEN_NAME) throw CompileError("(Line %d) Expecting name", CUR_TOKEN.line); // And the name IsolateTokenString(CUR_TOKEN); INC_TOKEN; // If it's an array, determine the dimensions if (CUR_TOKEN.type == TOKEN_ARRAY_OPEN) GetArrayInfo(type); // Add the parameter if (g_Object == NULL) var = func_ptr->AddParameter(type, token_string); if (CUR_TOKEN.type == TOKEN_RIGHT_BRACKET) { INC_TOKEN; break; } if (CUR_TOKEN.type != TOKEN_COMMA) throw CompileError("(Line %d) Need comma to seperate parameters", CUR_TOKEN.line); // Comma INC_TOKEN; } // Imported functions if (flags & FLAGS_FUNCTION_IMPORT) { if (g_Object == NULL) func_ptr->SingulariseAddresses(); if (CUR_TOKEN.type != TOKEN_END_OF_LINE) throw CompileError("(Line %d) Expecting end of line", CUR_TOKEN.line); } // Normal functions else { if (g_Object == NULL) func_ptr->FixAddresses(); cur_class->cur_function = func_ptr; ProcessBlock(flags | FLAGS_IN_FUNCTION); // Simply write the return code for void functions if (func_ptr->GetReturnType().id == VARIABLE_TYPEID_VOID) { if (g_Object) func_ptr->WriteReturn(g_Object); } else { // If a return type is needed, throw an error if one isn't found last if (!func_ptr->had_return) throw CompileError("(Line %d) Missing return value for function '%s'", CUR_TOKEN.line, func_ptr->GetName()); } } outfunc; }
void PressureTable::print(void) { int nPress = GetDimension1(); int nZm = GetDimension2(); int nZv = GetDimension3(); int nC = GetDimension4(); int nVar = GetNumberVariables(); cout << endl; cout << "------------------------------------------------------" << endl; cout << " Multi-Pressure Chemtable: " << TableFilename << endl; cout << "------------------------------------------------------" << endl; cout << " - Chemistry table type : " << ChemTableType << endl; cout << " - Combustion model : " << CombustionModel << endl; cout << " - Chemistry table size : " << nVar << " variables" << endl; cout << " " << nPress << " (Pressure) " << endl; cout << " " << nZm << " (Mean Mixture Fraction) "<< endl; cout << " " << nZv << " (Mixture Fraction Variance) " << endl; cout << " " << nC << " (Progress Variable) " << endl; cout << endl; cout << " - Input coordinates : " << endl; //cout << setiosflags(ios::fixed); cout << setprecision(4); //cout << dec; // Pressure vec double *vec = new double[nPress]; CopyCoordinate1(vec); cout <<" x1 : Pressure =" << "\t ["; cout.width(6); cout << vec[0] << " ... "; cout.width(6); cout << vec[nPress-1] << "]" << endl; delete [] vec; // Mixture Fraction Vec vec = new double[nZm]; CopyCoordinate2(vec); cout << " x2 : Zmean =" << "\t ["; cout.width(6); cout << vec[0] << " ... "; cout.width(6); cout << vec[nZm-1] << "]" << endl; delete [] vec; // Mixture Fraction Variance vec vec = new double[nZv]; CopyCoordinate3(vec); cout << " x3 : Zvar =" << "\t ["; cout.width(6); cout << vec[0] << " ... "; cout.width(6); cout << vec[nZv-1] << "]" << endl; delete [] vec; // Progress Variable vec vec = new double[nC]; CopyCoordinate4(vec); cout << " x4 : Prog =" << "\t ["; cout.width(6); cout << vec[0] << " ... "; cout.width(6); cout << vec[nC-1] << "]" << endl; delete [] vec; cout << endl; // Display variables names, min and max cout << " - Stored variables : " << endl; float minval, maxval; int mi1, mi2, mi3, ma1, ma2, ma3, mi4, ma4; for (int l = 0; l < nVar; l++) { GetArrayInfo(l, minval, maxval, mi1, mi2, mi3, mi4, ma1, ma2, ma3, ma4); cout.width(6); cout << l << ". "; cout.width(12); cout << VarNames[l] << " = ["; cout.width(12); cout << minval << " ... "; cout.width(12); cout << maxval << "]" << endl; } cout << "------------------------------------------------------" << endl; cout << endl; }