/* beginning of locals */
#define PARSER_HT_LOCALS 2
-#define PARSER_HT_SIZE 1024
+#define PARSER_HT_SIZE 128
#define TYPEDEF_HT_SIZE 16
enum parser_pot { POT_PAREN, POT_TERNARY1, POT_TERNARY2 };
if (CanConstFold(exprs[0], exprs[1]))
out = (ast_expression*)parser_const_vector(parser, vec3_mulvf(ConstV(0), 1.0/ConstF(1)));
else {
- out = (ast_expression*)ast_binary_new(ctx, INSTR_DIV_F,
- (ast_expression*)parser_const_float_1(parser),
- exprs[1]);
+ if (CanConstFold1(exprs[1])) {
+ out = (ast_expression*)parser_const_float(parser, 1.0 / ConstF(1));
+ } else {
+ out = (ast_expression*)ast_binary_new(ctx, INSTR_DIV_F,
+ (ast_expression*)parser_const_float_1(parser),
+ exprs[1]);
+ }
if (!out) {
compile_error(ctx, "internal error: failed to generate division");
return false;
exprs[0], exprs[1]);
} else {
/* there's no DIV_VF */
- out = (ast_expression*)ast_binary_new(ctx, INSTR_DIV_F,
- (ast_expression*)parser_const_float_1(parser),
- exprs[1]);
- if (!out)
+ if (CanConstFold1(exprs[1])) {
+ out = (ast_expression*)parser_const_float(parser, 1.0 / ConstF(1));
+ } else {
+ out = (ast_expression*)ast_binary_new(ctx, INSTR_DIV_F,
+ (ast_expression*)parser_const_float_1(parser),
+ exprs[1]);
+ }
+ if (!out) {
+ compile_error(ctx, "internal error: failed to generate division");
return false;
+ }
out = (ast_expression*)ast_binstore_new(ctx, assignop, INSTR_MUL_VF,
exprs[0], out);
}
}
*/
while (vec_size(sy->ops)) {
- if (sy->ops[vec_size(sy->ops)-1].paren == SY_PAREN_FUNC) {
+ if (vec_last(sy->ops).paren == SY_PAREN_FUNC) {
if (!parser_close_call(parser, sy))
return false;
break;
}
- if (sy->ops[vec_size(sy->ops)-1].paren == SY_PAREN_EXPR) {
+ if (vec_last(sy->ops).paren == SY_PAREN_EXPR) {
+ if (!vec_size(sy->out)) {
+ compile_error(vec_last(sy->ops).ctx, "empty paren expression");
+ vec_shrinkby(sy->ops, 1);
+ return false;
+ }
vec_shrinkby(sy->ops, 1);
return !functions_only;
}
- if (sy->ops[vec_size(sy->ops)-1].paren == SY_PAREN_INDEX) {
+ if (vec_last(sy->ops).paren == SY_PAREN_INDEX) {
if (functions_only)
return false;
/* pop off the parenthesis */
return false;
return true;
}
- if (sy->ops[vec_size(sy->ops)-1].paren == SY_PAREN_TERNARY) {
+ if (vec_last(sy->ops).paren == SY_PAREN_TERNARY) {
if (functions_only)
return false;
if (vec_last(parser->pot) != POT_TERNARY1) {
{
ast_expression *expr = NULL;
shunt sy;
+ size_t i;
bool wantop = false;
/* only warn once about an assignment in a truth value because the current code
* would trigger twice on: if(a = b && ...), once for the if-truth-value, once for the && part
onerr:
parser->lex->flags.noops = true;
+ for (i = 0; i < vec_size(sy.out); ++i) {
+ if (sy.out[i].out)
+ ast_unref(sy.out[i].out);
+ }
vec_free(sy.out);
vec_free(sy.ops);
return NULL;
if (!OPTS_FLAG(VARIADIC_ARGS) && var->expression.flags & AST_FLAG_VARIADIC) {
if (parsewarning(parser, WARN_VARIADIC_FUNCTION,
- "variadic function with implementation will not be able to access additional parameters"))
+ "variadic function with implementation will not be able to access additional parameters (try -fvariadic-args)"))
{
return false;
}
}
}
+ func = ast_function_new(ast_ctx(var), var->name, var);
+ if (!func) {
+ parseerror(parser, "failed to allocate function for `%s`", var->name);
+ ast_block_delete(block);
+ goto enderr;
+ }
+ vec_push(parser->functions, func);
+
parser_enterblock(parser);
for (parami = 0; parami < vec_size(var->expression.params); ++parami) {
if (!create_vector_members(param, me)) {
ast_block_delete(block);
- return false;
+ goto enderrfn;
}
for (e = 0; e < 3; ++e) {
}
}
- func = ast_function_new(ast_ctx(var), var->name, var);
- if (!func) {
- parseerror(parser, "failed to allocate function for `%s`", var->name);
- ast_block_delete(block);
- goto enderr;
- }
- vec_push(parser->functions, func);
-
if (var->argcounter) {
ast_value *argc = ast_value_new(ast_ctx(var), var->argcounter, TYPE_FLOAT);
parser_addlocal(parser, argc->name, (ast_expression*)argc);
if (!parser_create_array_setter_proto(parser, varargs, name)) {
ast_delete(varargs);
ast_block_delete(block);
- goto enderr;
+ goto enderrfn;
}
snprintf(name, sizeof(name), "%s##va##GET", var->name);
if (!parser_create_array_getter_proto(parser, varargs, varargs->expression.next, name)) {
ast_delete(varargs);
ast_block_delete(block);
- goto enderr;
+ goto enderrfn;
}
func->varargs = varargs;
}
return retval;
enderrfn:
+ (void)!parser_leaveblock(parser);
vec_pop(parser->functions);
ast_function_delete(func);
var->constval.vfunc = NULL;
enderr:
- (void)!parser_leaveblock(parser);
parser->function = old;
return false;
}
if (!var) {
if (name)
mem_d((void*)name);
- ast_delete(var);
return NULL;
}
}
if (OPTS_FLAG(UNTYPED_NIL))
util_htset(parser->htglobals, "nil", (void*)parser->nil);
+ parser->max_param_count = 1;
+
parser->const_vec[0] = ast_value_new(empty_ctx, "<vector.x>", TYPE_NOEXPR);
parser->const_vec[1] = ast_value_new(empty_ctx, "<vector.y>", TYPE_NOEXPR);
parser->const_vec[2] = ast_value_new(empty_ctx, "<vector.z>", TYPE_NOEXPR);