Esempio n. 1
0
void Parser::start() {
	while(buffer->getSize()) {
		Token* token = buffer->peek(0);
		
		switch(token->type) {
			case IN: {
				match(IN);
				Token* tokType = match(TYPE);
				Token* tokName = match(VARIABLE);
				match(END);
				
				Variable* variable = variables->find(variables->root, tokName->data, &currentFunction);
				if(variable == NULL) {
					Variable *variable = (Variable*) malloc(sizeof(Variable));
					variable->name = (char*)malloc(sizeof(tokName->data));
					strncpy(variable->name, tokName->data, strlen(tokName->data));
					variable->type = VariableType(variabletypes->find(variabletypes->root, tokType->data)->type);
					variable->function = currentFunction;
					in->push(variables->insert(variables->root, variable));
				}
				else {
					printf("[Parser Error] Redefinition of variable %s\n", variable->name);
					free(variable);
				}
				
				break;
			}
			case OUT: {
				match(OUT);
				Token* tokType = match(TYPE);
				Token* tokName = match(VARIABLE);
				match(END);
				
				Variable* variable = variables->find(variables->root, tokName->data, &currentFunction);
				if(variable == NULL) {
					Variable *variable = (Variable*) malloc(sizeof(Variable));
					variable->name = (char*)malloc(sizeof(tokName->data));
					strncpy(variable->name, tokName->data, strlen(tokName->data));
					variable->type = VariableType(variabletypes->find(variabletypes->root, tokType->data)->type);
					variable->function = currentFunction;
					out->push(variables->insert(variables->root, variable));
				}
				else {
					printf("[Parser Error] Redefinition of variable %s\n", variable->name);
					free(variable);
				}
				
				break;
			}
			case UNIFORM: {
				match(UNIFORM);
				Token* tokType = match(TYPE);
				Token* tokName = match(VARIABLE);
				match(END);
				
				Variable* variable = variables->find(variables->root, tokName->data, &currentFunction);
				if(variable == NULL) {
					Variable *variable = (Variable*) malloc(sizeof(Variable));
					variable->name = (char*)malloc(sizeof(tokName->data));
					strncpy(variable->name, tokName->data, strlen(tokName->data));
					variable->type = VariableType(variabletypes->find(variabletypes->root, tokType->data)->type);
					variable->function = currentFunction;
					uniform->push(variables->insert(variables->root, variable));
				}
				else {
					printf("[Parser Error] Redefinition of variable %s\n", variable->name);
					free(variable);
				}
				
				break;
			}
			case TYPE: {
				Token* tokType = match(TYPE);
				Token* tokName = match(VARIABLE);
				
				if(buffer->peek(0)->type == LPAR) {
					match(LPAR);
					
					Function* function = functions->findFunction(functions->root, tokName->data);
					if(function != NULL) {
						printf("[Parser Error] Redefinition of function %s\n", function->name);
						free(function);
						break;
					}
					
					Block* block = new Block();
					blockList->push(block);
					int blockId = blockList->getSize();
					
					Function* function = (Function*) malloc(sizeof(Function));
					strncpy(function->name, tokName->data, strlen(tokName->data));
					function->ret = VariableType(variabletypes->find(variabletypes->root, tokType->data)->type);
					function->arguments = getArguments();
					function->block = blockId;
					currentFunction = functions->addFunction(functions->root, function);
					
					processBlock(block);
					
					currentFunction = 0;
					
					break;
				}
				
				Variable* variable = variables->find(variables->root, tokName->data, &currentFunction);
				if(variable == NULL) {
					Variable *variable = (Variable*) malloc(sizeof(Variable));
					variable->name = (char*)malloc(sizeof(tokName->data));
					strncpy(variable->name, tokName->data, strlen(tokName->data));
					variable->type = VariableType(variabletypes->find(variabletypes->root, tokType->data)->type);
					variable->function = currentFunction;
					variables->insert(variables->root, variable);
				}
				else {
					printf("[Parser Error] Redefinition of variable %s\n", variable->name);
					free(variable);
				}
				
				break;
			}
			default: {
				printf("[Parser Error] Invalid token %s(%d) detected!\n", token->data, token->type);
				return;
			}
		}
	}
}
Esempio n. 2
0
VariableType StringNode::getType() const { return VariableType(BuiltIns::ASCII_string_type, true); }
void
LabelAttributes::SetFromNode(DataNode *parentNode)
{
    if(parentNode == 0)
        return;

    DataNode *searchNode = parentNode->GetNode("LabelAttributes");
    if(searchNode == 0)
        return;

    DataNode *node;
    if((node = searchNode->GetNode("varType")) != 0)
    {
        // Allow enums to be int or string in the config file
        if(node->GetNodeType() == INT_NODE)
        {
            int ival = node->AsInt();
            if(ival >= 0 && ival < 10)
                SetVarType(VariableType(ival));
        }
        else if(node->GetNodeType() == STRING_NODE)
        {
            VariableType value;
            if(VariableType_FromString(node->AsString(), value))
                SetVarType(value);
        }
    }
    if((node = searchNode->GetNode("legendFlag")) != 0)
        SetLegendFlag(node->AsBool());
    if((node = searchNode->GetNode("showNodes")) != 0)
        SetShowNodes(node->AsBool());
    if((node = searchNode->GetNode("showCells")) != 0)
        SetShowCells(node->AsBool());
    if((node = searchNode->GetNode("restrictNumberOfLabels")) != 0)
        SetRestrictNumberOfLabels(node->AsBool());
    if((node = searchNode->GetNode("drawLabelsFacing")) != 0)
    {
        // Allow enums to be int or string in the config file
        if(node->GetNodeType() == INT_NODE)
        {
            int ival = node->AsInt();
            if(ival >= 0 && ival < 3)
                SetDrawLabelsFacing(LabelDrawFacing(ival));
        }
        else if(node->GetNodeType() == STRING_NODE)
        {
            LabelDrawFacing value;
            if(LabelDrawFacing_FromString(node->AsString(), value))
                SetDrawLabelsFacing(value);
        }
    }
    if((node = searchNode->GetNode("labelDisplayFormat")) != 0)
    {
        // Allow enums to be int or string in the config file
        if(node->GetNodeType() == INT_NODE)
        {
            int ival = node->AsInt();
            if(ival >= 0 && ival < 3)
                SetLabelDisplayFormat(LabelIndexDisplay(ival));
        }
        else if(node->GetNodeType() == STRING_NODE)
        {
            LabelIndexDisplay value;
            if(LabelIndexDisplay_FromString(node->AsString(), value))
                SetLabelDisplayFormat(value);
        }
    }
    if((node = searchNode->GetNode("numberOfLabels")) != 0)
        SetNumberOfLabels(node->AsInt());
    if((node = searchNode->GetNode("specifyTextColor1")) != 0)
        SetSpecifyTextColor1(node->AsBool());
    if((node = searchNode->GetNode("textColor1")) != 0)
        textColor1.SetFromNode(node);
    if((node = searchNode->GetNode("textHeight1")) != 0)
        SetTextHeight1(node->AsFloat());
    if((node = searchNode->GetNode("specifyTextColor2")) != 0)
        SetSpecifyTextColor2(node->AsBool());
    if((node = searchNode->GetNode("textColor2")) != 0)
        textColor2.SetFromNode(node);
    if((node = searchNode->GetNode("textHeight2")) != 0)
        SetTextHeight2(node->AsFloat());
    if((node = searchNode->GetNode("horizontalJustification")) != 0)
    {
        // Allow enums to be int or string in the config file
        if(node->GetNodeType() == INT_NODE)
        {
            int ival = node->AsInt();
            if(ival >= 0 && ival < 3)
                SetHorizontalJustification(LabelHorizontalAlignment(ival));
        }
        else if(node->GetNodeType() == STRING_NODE)
        {
            LabelHorizontalAlignment value;
            if(LabelHorizontalAlignment_FromString(node->AsString(), value))
                SetHorizontalJustification(value);
        }
    }
    if((node = searchNode->GetNode("verticalJustification")) != 0)
    {
        // Allow enums to be int or string in the config file
        if(node->GetNodeType() == INT_NODE)
        {
            int ival = node->AsInt();
            if(ival >= 0 && ival < 3)
                SetVerticalJustification(LabelVerticalAlignment(ival));
        }
        else if(node->GetNodeType() == STRING_NODE)
        {
            LabelVerticalAlignment value;
            if(LabelVerticalAlignment_FromString(node->AsString(), value))
                SetVerticalJustification(value);
        }
    }
    if((node = searchNode->GetNode("depthTestMode")) != 0)
    {
        // Allow enums to be int or string in the config file
        if(node->GetNodeType() == INT_NODE)
        {
            int ival = node->AsInt();
            if(ival >= 0 && ival < 3)
                SetDepthTestMode(DepthTestMode(ival));
        }
        else if(node->GetNodeType() == STRING_NODE)
        {
            DepthTestMode value;
            if(DepthTestMode_FromString(node->AsString(), value))
                SetDepthTestMode(value);
        }
    }
    if((node = searchNode->GetNode("formatTemplate")) != 0)
        SetFormatTemplate(node->AsString());
}
LabelAttributes::VariableType
LabelAttributes::GetVarType() const
{
    return VariableType(varType);
}
Esempio n. 5
0
void ShaderGenerator::generate (const ShaderParameters& shaderParams, Shader& shader, const vector<ShaderInput*>& outputs)
{
	// Global scopes
	VariableScope&	globalVariableScope	= shader.getGlobalScope();
	ValueScope		globalValueScope;

	// Init state
	m_state.setShader(shaderParams, shader);
	DE_ASSERT(m_state.getExpressionFlags() == 0);

	// Reserve some scalars for gl_Position & dEQP_Position
	ReservedScalars reservedScalars;
	if (shader.getType() == Shader::TYPE_VERTEX)
		m_state.getVariableManager().reserve(reservedScalars, 4*2);

	// Push global scopes
	m_varManager.pushVariableScope(globalVariableScope);
	m_varManager.pushValueScope(globalValueScope);

	// Init shader outputs.
	{
		for (vector<ShaderInput*>::const_iterator i = outputs.begin(); i != outputs.end(); i++)
		{
			const ShaderInput*	input		= *i;
			Variable*			variable	= m_state.getVariableManager().allocate(input->getVariable()->getType(), Variable::STORAGE_SHADER_OUT, input->getVariable()->getName());

			m_state.getVariableManager().setValue(variable, input->getValueRange());
		}

		if (shader.getType() == Shader::TYPE_FRAGMENT)
		{
			// gl_FragColor
			// \todo [2011-11-22 pyry] Multiple outputs from fragment shader!
			Variable*	fragColorVar	= m_state.getVariableManager().allocate(VariableType(VariableType::TYPE_FLOAT, 4), Variable::STORAGE_SHADER_OUT, getFragColorName(m_state));
			ValueRange	valueRange(fragColorVar->getType());

			valueRange.getMin() = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
			valueRange.getMax() = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);

			fragColorVar->setLayoutLocation(0); // Bind color output to location 0 (applies to GLSL ES 3.0 onwards).

			m_state.getVariableManager().setValue(fragColorVar, valueRange.asAccess());
		}
	}

	// Construct shader code.
	{
		Function& main = shader.getMain();
		main.setReturnType(VariableType(VariableType::TYPE_VOID));

		if (shaderParams.randomize)
		{
			FunctionGenerator funcGen(m_state, main);

			// Mandate assignment into to all shader outputs in main()
			const vector<Variable*>& liveVars = globalVariableScope.getLiveVariables();
			for (vector<Variable*>::const_iterator i = liveVars.begin(); i != liveVars.end(); i++)
			{
				Variable* variable = *i;
				if (variable->getStorage() == Variable::STORAGE_SHADER_OUT)
					funcGen.requireAssignment(variable);
			}

			funcGen.generate();
		}
		else
		{
			if (shader.getType() == Shader::TYPE_VERTEX)
				genVertexPassthrough(m_state, shader);
			else
			{
				DE_ASSERT(shader.getType() == Shader::TYPE_FRAGMENT);
				genFragmentPassthrough(m_state, shader);
			}
		}

		if (shader.getType() == Shader::TYPE_VERTEX)
		{
			// Add gl_Position = dEQP_Position;
			m_state.getVariableManager().release(reservedScalars);

			Variable* glPosVariable = m_state.getVariableManager().allocate(VariableType(VariableType::TYPE_FLOAT, 4), Variable::STORAGE_SHADER_OUT, "gl_Position");
			Variable* qpPosVariable = m_state.getVariableManager().allocate(VariableType(VariableType::TYPE_FLOAT, 4), Variable::STORAGE_SHADER_IN, "dEQP_Position");

			ValueRange valueRange(glPosVariable->getType());

			valueRange.getMin() = tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f);
			valueRange.getMax() = tcu::Vec4( 1.0f,  1.0f, 0.0f, 1.0f);

			m_state.getVariableManager().setValue(qpPosVariable, valueRange.asAccess()); // \todo [2011-05-24 pyry] No expression should be able to use gl_Position or dEQP_Position..

			createAssignment(main.getBody(), glPosVariable, qpPosVariable);
		}
	}

	// Declare live global variables.
	{
		vector<Variable*> liveVariables;
		std::copy(globalVariableScope.getLiveVariables().begin(), globalVariableScope.getLiveVariables().end(), std::inserter(liveVariables, liveVariables.begin()));

		vector<Variable*> createDeclarationStatementVars;

		for (vector<Variable*>::iterator i = liveVariables.begin(); i != liveVariables.end(); i++)
		{
			Variable*		variable	= *i;
			const char*		name		= variable->getName();
			bool			declare		= !deStringBeginsWith(name, "gl_"); // Do not declare built-in types.

			// Create input entries (store value range) if necessary
			vector<ShaderInput*>& inputs	= shader.getInputs();
			vector<ShaderInput*>& uniforms	= shader.getUniforms();

			switch (variable->getStorage())
			{
				case Variable::STORAGE_SHADER_IN:
				{
					const ValueEntry* value = m_state.getVariableManager().getValue(variable);

					inputs.reserve(inputs.size()+1);
					inputs.push_back(new ShaderInput(variable, value->getValueRange()));
					break;
				}

				case Variable::STORAGE_UNIFORM:
				{
					const ValueEntry* value = m_state.getVariableManager().getValue(variable);

					uniforms.reserve(uniforms.size()+1);
					uniforms.push_back(new ShaderInput(variable, value->getValueRange()));
					break;
				}

				default:
					break;
			}

			if (declare)
				createDeclarationStatementVars.push_back(variable);
			else
			{
				// Just move to global scope without declaration statement.
				m_state.getVariableManager().declareVariable(variable);
			}
		}

		// All global initializers must be constant expressions, no variable allocation is allowed
		DE_ASSERT(m_state.getExpressionFlags() == 0);
		m_state.pushExpressionFlags(CONST_EXPR|NO_VAR_ALLOCATION);

		// Create declaration statements
		for (vector<Variable*>::iterator i = createDeclarationStatementVars.begin(); i != createDeclarationStatementVars.end(); i++)
		{
			shader.getGlobalStatements().reserve(shader.getGlobalStatements().size());
			shader.getGlobalStatements().push_back(new DeclarationStatement(m_state, *i));
		}

		m_state.popExpressionFlags();
	}

	// Pop global scopes
	m_varManager.popVariableScope();
	m_varManager.popValueScope();

	// Fill undefined (unused) components in inputs with dummy values
	fillUndefinedShaderInputs(shader.getInputs());
	fillUndefinedShaderInputs(shader.getUniforms());

	// Tokenize shader and write source
	{
		TokenStream tokenStr;
		shader.tokenize(m_state, tokenStr);

		std::ostringstream	str;
		PrettyPrinter		printer(str);

		// Append #version if necessary.
		if (m_state.getProgramParameters().version == VERSION_300)
			str << "#version 300 es\n";

		printer.append(tokenStr);
		shader.setSource(str.str().c_str());
	}
}
Esempio n. 6
0
void BuiltIns::defineBuiltIns()
{
    auto factory = SymbolFactory{ };

    auto makeRef = [](auto&& type, bool is_const) { return VariableType(TypeFactory::getReference(type.get()), is_const); };

    auto global_scope = std::make_shared<GlobalScope>();
   
    auto int_          = factory.makeStruct("int", new StructScope("int", global_scope.get()));
    auto ref_int       = makeRef(int_, false);
    auto const_ref_int = makeRef(int_, true);

    auto char_          = factory.makeStruct("char", new StructScope("char", global_scope.get()));
    auto ref_char       = makeRef(char_, false);
    auto const_ref_char = makeRef(char_, true);

    auto str           = factory.makeStruct("string", new StructScope("string", global_scope.get()));
    auto ref_str       = makeRef(str, false);
    auto const_ref_str = makeRef(str, true);

    auto int_builtin  = VariableType(new BuiltInTypeSymbol("~~int", Comp::config().int_size), false);
    auto char_builtin = VariableType(new BuiltInTypeSymbol("~~char", Comp::config().int_size), false);

    auto simple_traits = FunctionTraits::simple();
    auto op_traits     = FunctionTraits::methodOper();
    auto meth_traits   = FunctionTraits::method();
    auto constr_traits = FunctionTraits::constructor();

    auto tp = FunctionType(int_.get(), {ref_int, int_.get()});

    auto void_type = std::make_unique<BuiltInTypeSymbol>("void", 0);

    global_scope -> define(factory.makeFunction("putchar", FunctionType(void_type.get(), {char_.get()}), simple_traits, false));
    global_scope -> define(factory.makeFunction("getchar", FunctionType(int_.get(), { }), simple_traits, false));

    auto string_builtin = VariableType(new BuiltInTypeSymbol("~~string", 256), false);    
    str -> defineMember(factory.makeVariable("~~impl", string_builtin, VariableSymbolType::FIELD));

    auto str_tp = FunctionType(ref_str, {ref_str, const_ref_str});
    
    int_ -> defineMember(factory.makeVariable("~~impl", int_builtin, VariableSymbolType::FIELD));
    
    int_ -> defineMethod(factory.makeFunction("int", FunctionType(ref_int, {ref_int}), constr_traits, false));
    int_ -> defineMethod(factory.makeFunction("int", FunctionType(ref_int, {ref_int, const_ref_int}), constr_traits, false));
    
    int_ -> defineMethod(factory.makeFunction("operator=", FunctionType(ref_int, {ref_int, const_ref_int}), op_traits, false));

    int_ -> defineMethod(factory.makeFunction("operator+", tp, op_traits, false));
    int_ -> defineMethod(factory.makeFunction("operator-", tp, op_traits, false));
    int_ -> defineMethod(factory.makeFunction("operator*", tp, op_traits, false));
    int_ -> defineMethod(factory.makeFunction("operator/", tp, op_traits, false));
    int_ -> defineMethod(factory.makeFunction("operator%", tp, op_traits, false));
    int_ -> defineMethod(factory.makeFunction("operator==", tp, op_traits, false));
    int_ -> defineMethod(factory.makeFunction("operator!=", tp, op_traits, false));
    int_ -> defineMethod(factory.makeFunction("operator&&", tp, op_traits, false));
    int_ -> defineMethod(factory.makeFunction("operator||", tp, op_traits, false));

    int_ -> defineMethod(factory.makeFunction("int", FunctionType(ref_int, {ref_int, char_.get()}), constr_traits, false));

    char_ -> defineMember(factory.makeVariable("~~impl", char_builtin, VariableSymbolType::FIELD));

    char_ -> defineMethod(factory.makeFunction("char", FunctionType(ref_char, {ref_char}), constr_traits, false));
    char_ -> defineMethod(factory.makeFunction("char", FunctionType(ref_char, {ref_char, const_ref_char}), constr_traits, false));
    char_ -> defineMethod(factory.makeFunction("char", FunctionType(ref_char, {ref_char, const_ref_int}), constr_traits, false));

    char_ -> defineMethod(factory.makeFunction("operator=", FunctionType(ref_char, {ref_char, const_ref_char}), constr_traits, false));

    str -> defineMethod(factory.makeFunction("string", str_tp, constr_traits, false));
    str -> defineMethod(factory.makeFunction("length", FunctionType(int_.get(), {ref_str}), meth_traits, false));

    str -> defineMethod(factory.makeFunction("operator[]", FunctionType(ref_char, {ref_str, int_.get()}), op_traits, false));
    str -> defineMethod(factory.makeFunction("operator+", FunctionType(str.get(), {ref_str, const_ref_str}), op_traits, false));
    str -> defineMethod(factory.makeFunction("operator=", str_tp, op_traits, false));

    global_scope -> define(factory.makeFunction("print", FunctionType(void_type.get(), {const_ref_str}), simple_traits, false));
    
    BuiltIns::int_type          = int_.get();
    BuiltIns::char_type         = char_.get();
    BuiltIns::ASCII_string_type = str.get();
    BuiltIns::void_type         = void_type.get();
    
    global_scope -> define(std::move(void_type));
    global_scope -> define(std::move(int_));
    global_scope -> define(std::move(str));
    global_scope -> define(std::move(char_));
    
    BuiltIns::global_scope      = global_scope;
}
Esempio n. 7
0
void CheckVisitor::visit(ReturnNode* node)
{
    node -> expr() -> accept(*this);

    if ( node -> isInInlineCall() )
        return;

    if ( function_scopes.empty() )
        throw SemanticError("return is not in a function");

    auto enclosing_function = function_scopes.top() -> func;
    node -> function(enclosing_function);

    auto unqualified_type = node -> expr() -> getType().unqualified();
    if ( unqualified_type -> isObjectType() )
    {
        auto obj_type = static_cast<const ObjectType*>(unqualified_type);
        auto ref_to_obj_type = TypeFactory::getReference(obj_type);
//        auto copy_constr = obj_type -> resolveMethod(obj_type -> typeName(), {VariableType(TypeFactory::getReference(obj_type), true)});
        auto copy_constr = obj_type -> methodWith(obj_type -> typeName(), {ref_to_obj_type, VariableType(ref_to_obj_type, true)});

        if ( copy_constr == nullptr )
            throw SemanticError("Cannot initialize return value of type '" + enclosing_function -> type().returnType().getName() + "' with value of type '" + obj_type -> typeName() + "'");

        checkCall(copy_constr, {valueOf(node -> expr())});
    }
}