Exemplo n.º 1
0
bool Parser::expr_err(ExprNode *&, int stage, int)
{
    int i;

    if(stage == 35)
        PossibleError("Suspicious identifier found in function!\n"
                      "If you want to call a function make sure the function you call has been declared.\n"
                      "If you call an internal function, make sure you have included 'functions.inc'.");

    for(i = 0; (expr_parser_error_table[i].stage >= 0) && (expr_parser_error_table[i].expected != NULL); i++)
    {
        if(expr_parser_error_table[i].stage == stage)
            Expectation_Error(expr_parser_error_table[i].expected);
    }

    Expectation_Error("valid function expression");

    // unreachable, Expectation_Error stops parsing
    return false;
}
Exemplo n.º 2
0
bool Parser::expr_call(ExprNode *&current, int stage, int op)
{
    ExprNode *node = NULL;

    if(current == NULL)
        return false;

    node = new_expr_node(stage, op);

    if(Token.Data != NULL)
    {
        node->call.fn = *((FUNCTION_PTR)Token.Data);
        (void)dynamic_cast<FunctionVM*>(sceneData->functionContextFactory)->GetFunctionAndReference(node->call.fn);
    }
    else
        node->call.fn = 0;
    node->call.token = Token.Function_Id;
    node->call.name = POV_STRDUP(Token.Token_String);
    while(current->child != NULL)
        current = current->child;

    current->child = node;
    node->parent = current;
    current = node;

    if(expr_get_token() != LEFT_PAREN_TOKEN)
        Expectation_Error("(");

    current->child = node = parse_expr();
    while(expr_get_token() == COMMA_TOKEN)
    {
        node->next = parse_expr();
        node->next->parent = node->parent;
        node = node->next;
    }

    if(Token.Token_Id != RIGHT_PAREN_TOKEN)
        Expectation_Error(")");

    return true;
}
Exemplo n.º 3
0
FUNCTION_PTR Parser::Parse_DeclareFunction(int *token_id, const char *fn_name, bool is_local)
{
	FUNCTION_PTR ptr = (FUNCTION_PTR)POV_MALLOC(sizeof(FUNCTION), "Function ID");
	ExprNode *expression = NULL;
	FunctionCode function;

	// default type is float function
	*token_id = FUNCT_ID_TOKEN;

	FNCode f(this, &function, is_local, fn_name);
	f.Parameter();

	Parse_Begin();

	Get_Token();
	if(Token.Token_Id == INTERNAL_TOKEN)
	{
		GET(LEFT_PAREN_TOKEN);

		Get_Token();
		if(Token.Function_Id != FLOAT_TOKEN)
			Expectation_Error("internal function identifier");
		expression = FNSyntax_GetTrapExpression((unsigned int)(Token.Token_Float));

		function.flags = FN_INLINE_FLAG;

		GET(RIGHT_PAREN_TOKEN);
	}
	else if(Token.Token_Id == TRANSFORM_TOKEN)
	{
		if(function.parameter_cnt != 0)
			Error("Function parameters for transform functions are not allowed.");

		expression = FNSyntax_GetTrapExpression(1); // 1 refers to POVFPU_TrapSTable[1] = f_transform [trf]

		function.private_copy_method = (FNCODE_PRIVATE_COPY_METHOD)Copy_Transform;
		function.private_destroy_method = (FNCODE_PRIVATE_DESTROY_METHOD)Destroy_Transform;

		function.private_data = reinterpret_cast<void *>(Parse_Transform_Block());

		function.return_size = 3; // returns a 3d vector!!!

		// function type is vector function
		*token_id = VECTFUNCT_ID_TOKEN;
	}
	else if(Token.Token_Id == SPLINE_TOKEN)
	{
		if(function.parameter_cnt != 0)
			Error("Function parameters for spline functions are not allowed.");

		Experimental_Flag |= EF_SPLINE;

		expression = FNSyntax_GetTrapExpression(2); // 2 refers to POVFPU_TrapSTable[2] = f_spline [trf]

		function.private_copy_method = (FNCODE_PRIVATE_COPY_METHOD)Copy_Spline;
		function.private_destroy_method = (FNCODE_PRIVATE_DESTROY_METHOD)Destroy_Spline;

		Parse_Begin();
		function.private_data = reinterpret_cast<void *>(Parse_Spline());
		Parse_End();

		function.return_size = (reinterpret_cast<SPLINE *>(function.private_data))->Terms; // returns a 2d, 3d, 4d or 5d vector!!!

		// function type is vector function
		*token_id = VECTFUNCT_ID_TOKEN;
	}
	else if(Token.Token_Id == PIGMENT_TOKEN)
	{
		if(function.parameter_cnt != 0)
			Error("Function parameters for pigment functions are not allowed.");

		expression = FNSyntax_GetTrapExpression(0); // 0 refers to POVFPU_TrapSTable[0] = f_pigment [trf]

		function.private_copy_method = (FNCODE_PRIVATE_COPY_METHOD)Copy_Pigment;
		function.private_destroy_method = (FNCODE_PRIVATE_DESTROY_METHOD)Destroy_Pigment;

		Parse_Begin();
		function.private_data = reinterpret_cast<void *>(Create_Pigment());
		Parse_Pigment(reinterpret_cast<PIGMENT **>(&function.private_data));
		Parse_End();
		Post_Pigment(reinterpret_cast<PIGMENT *>(function.private_data));

		function.return_size = 5; // returns a color!!!

		// function type is vector function
		*token_id = VECTFUNCT_ID_TOKEN;
	}
	else if(Token.Token_Id == PATTERN_TOKEN)
	{
		if(function.parameter_cnt != 0)
			Error("Function parameters for pattern functions are not allowed.");

		expression = FNSyntax_GetTrapExpression(77); // 77 refers to POVFPU_TrapTable[77] = f_pattern [trf]

		function.private_copy_method = (FNCODE_PRIVATE_COPY_METHOD)Copy_Pigment;
		function.private_destroy_method = (FNCODE_PRIVATE_DESTROY_METHOD)Destroy_Pigment;

		Parse_Begin();
		function.private_data = reinterpret_cast<void *>(Create_Pigment()); // Yes, this is a pigment! [trf]
		Parse_PatternFunction(reinterpret_cast<TPATTERN *>(function.private_data));
		Parse_End();
		Post_Pigment(reinterpret_cast<PIGMENT *>(function.private_data));
	}
	else if(Token.Token_Id == STRING_LITERAL_TOKEN)
	{
		f.SetFlag(2, Token.Token_String);
		Get_Token();
		if(Token.Token_Id == COMMA_TOKEN)
		{
			Get_Token();
			if(Token.Token_Id != STRING_LITERAL_TOKEN)
				Expectation_Error("valid function expression");
			f.SetFlag(1, Token.Token_String);
		}
		else
		{
			Unget_Token();
			expression = FNSyntax_ParseExpression();
		}
	}
	else
	{
		Unget_Token();
		expression = FNSyntax_ParseExpression();
	}

	f.Compile(expression);
	FNSyntax_DeleteExpression(expression);

	Parse_End();

	*ptr = sceneData->functionVM->AddFunction(&function);

	return ptr;
}
Exemplo n.º 4
0
UCS2 *Parser::Parse_String(bool pathname, bool require)
{
	UCS2 *New = NULL;
	int len = 0;

	EXPECT
		CASE(STRING_LITERAL_TOKEN)
			New = String_To_UCS2(Token.Token_String, pathname);
			EXIT
		END_CASE

		CASE(STR_TOKEN)
			New = Parse_Str(pathname);
			EXIT
		END_CASE

		CASE(VSTR_TOKEN)
			New = Parse_VStr(pathname);
			EXIT
		END_CASE

		CASE(CONCAT_TOKEN)
			New = Parse_Concat(pathname);
			EXIT
		END_CASE

		CASE(CHR_TOKEN)
			New = Parse_Chr(pathname);
			EXIT
		END_CASE

		CASE(DATETIME_TOKEN)
			New = Parse_Datetime(pathname);
			EXIT
		END_CASE

		CASE(SUBSTR_TOKEN)
			New = Parse_Substr(pathname);
			EXIT
		END_CASE

		CASE(STRUPR_TOKEN)
			New = Parse_Strupr(pathname);
			EXIT
		END_CASE

		CASE(STRLWR_TOKEN)
			New = Parse_Strlwr(pathname);
			EXIT
		END_CASE

		CASE(STRING_ID_TOKEN)
			len = UCS2_strlen(reinterpret_cast<UCS2 *>(Token.Data)) + 1;
			New = reinterpret_cast<UCS2 *>(POV_MALLOC(len * sizeof(UCS2), "UCS2 String"));
			POV_MEMMOVE(reinterpret_cast<void *>(New), reinterpret_cast<void *>(Token.Data), len * sizeof(UCS2));
			EXIT
		END_CASE

		OTHERWISE
			if(require)
				Expectation_Error("string expression");
			else
			{
				UNGET
				EXIT
			}
		END_CASE
	END_EXPECT

	return New;
}
Exemplo n.º 5
0
UCS2 *Parser::Parse_String(bool pathname, bool require)
{
    UCS2 *New = nullptr;
    int len = 0;
    const UCS2String* pString;
    const StringValue* stringValue = nullptr;

    EXPECT
        CASE(STRING_LITERAL_TOKEN)
            /// @todo Add back support for non-ASCII string encodings.
            stringValue = dynamic_cast<const StringValue*>(mToken.raw.value.get());
            POV_PARSER_ASSERT(stringValue != nullptr);

            if (pathname)
            {
                // Historically, escape sequences were ignored when parsing for a filename.
                // As of POV-Ray v3.8, this has been changed.

                if (sceneData->EffectiveLanguageVersion() >= 380)
                {
                    if (stringValue->IsAmbiguous())
                    {
#if POV_BACKSLASH_IS_PATH_SEPARATOR
                        Warning("Backslash encountered while parsing for a filename."
                                " As of POV-Ray v3.8, this is interpreted as an escape sequence just like in any other string literal."
                                " If this is supposed to be a path separator, use a forward slash instead.");
#endif

                    }
                    pString = &stringValue->GetData();
                }
                else
                {
                    if (stringValue->IsAmbiguous())
                    {
#if POV_BACKSLASH_IS_PATH_SEPARATOR
                        Warning("Backslash encountered while parsing for a filename."
                                " In legacy (pre-v3.8) scenes, this is NOT interpreted as the start of an escape sequence."
                                " However, for future compatibility it is recommended to use a forward slash as path separator instead.");
#else
                        Warning("Backslash encountered while parsing for a filename."
                                " In legacy (pre-v3.8) scenes, this is NOT interpreted as the start of an escape sequence.");
#endif
                    }
                    pString = &stringValue->GetFileName();
                }
            }
            else
            {
                pString = &stringValue->GetData();
            }

            len = pString->size() + 1;
            New = reinterpret_cast<UCS2 *>(POV_MALLOC(len * sizeof(UCS2), "UCS2 String"));
            std::memcpy(reinterpret_cast<void *>(New),
                        reinterpret_cast<const void *>(pString->c_str()),
                        len * sizeof(UCS2));
            EXIT
        END_CASE

        CASE(STR_TOKEN)
            New = Parse_Str(pathname);
            EXIT
        END_CASE

        CASE(VSTR_TOKEN)
            New = Parse_VStr(pathname);
            EXIT
        END_CASE

        CASE(CONCAT_TOKEN)
            New = Parse_Concat(pathname);
            EXIT
        END_CASE

        CASE(CHR_TOKEN)
            New = Parse_Chr(pathname);
            EXIT
        END_CASE

        CASE(DATETIME_TOKEN)
            New = Parse_Datetime(pathname);
            EXIT
        END_CASE

        CASE(SUBSTR_TOKEN)
            New = Parse_Substr(pathname);
            EXIT
        END_CASE

        CASE(STRUPR_TOKEN)
            New = Parse_Strupr(pathname);
            EXIT
        END_CASE

        CASE(STRLWR_TOKEN)
            New = Parse_Strlwr(pathname);
            EXIT
        END_CASE

        CASE(STRING_ID_TOKEN)
            len = UCS2_strlen(CurrentTokenDataPtr<UCS2*>()) + 1;
            New = reinterpret_cast<UCS2 *>(POV_MALLOC(len * sizeof(UCS2), "UCS2 String"));
            std::memcpy(reinterpret_cast<void *>(New), CurrentTokenDataPtr<void*>(), len * sizeof(UCS2));
            EXIT
        END_CASE

        OTHERWISE
            if(require)
                Expectation_Error("string expression");
            else
            {
                UNGET
                EXIT
            }
        END_CASE
    END_EXPECT

    return New;
}