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;
}
示例#3
0
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;
}