Initial movement to std::vector

This commit is contained in:
Dale Weiler 2015-01-14 23:34:43 -05:00
parent d4deaa35ca
commit 67a3c9b031
6 changed files with 394 additions and 433 deletions

View file

@ -5,7 +5,8 @@ CXXFLAGS = \
-Wextra \ -Wextra \
-fno-exceptions \ -fno-exceptions \
-fno-rtti \ -fno-rtti \
-MD -MD \
-g3
CSRCS = \ CSRCS = \
ast.cpp \ ast.cpp \

134
ast.cpp
View file

@ -1,3 +1,5 @@
#include <new>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -10,6 +12,7 @@
if (!self) { \ if (!self) { \
return NULL; \ return NULL; \
} \ } \
new (self) T(); \
ast_node_init((ast_node*)self, ctx, TYPE_##T); \ ast_node_init((ast_node*)self, ctx, TYPE_##T); \
( (ast_node*)self )->destroy = (ast_node_delete*)destroyfn ( (ast_node*)self )->destroy = (ast_node_delete*)destroyfn
@ -89,7 +92,6 @@ static void ast_expression_init(ast_expression *self,
self->next = NULL; self->next = NULL;
self->outl = NULL; self->outl = NULL;
self->outr = NULL; self->outr = NULL;
self->params = NULL;
self->count = 0; self->count = 0;
self->varparam = NULL; self->varparam = NULL;
self->flags = 0; self->flags = 0;
@ -99,13 +101,10 @@ static void ast_expression_init(ast_expression *self,
static void ast_expression_delete(ast_expression *self) static void ast_expression_delete(ast_expression *self)
{ {
size_t i;
if (self->next) if (self->next)
ast_delete(self->next); ast_delete(self->next);
for (i = 0; i < vec_size(self->params); ++i) { for (auto &it : self->params)
ast_delete(self->params[i]); ast_delete(it);
}
vec_free(self->params);
if (self->varparam) if (self->varparam)
ast_delete(self->varparam); ast_delete(self->varparam);
} }
@ -118,40 +117,38 @@ static void ast_expression_delete_full(ast_expression *self)
ast_value* ast_value_copy(const ast_value *self) ast_value* ast_value_copy(const ast_value *self)
{ {
size_t i;
const ast_expression *fromex; const ast_expression *fromex;
ast_expression *selfex; ast_expression *selfex;
ast_value *cp = ast_value_new(self->expression.node.context, self->name, self->expression.vtype); ast_value *cp = ast_value_new(self->expression.node.context, self->name, self->expression.vtype);
if (self->expression.next) { if (self->expression.next) {
cp->expression.next = ast_type_copy(self->expression.node.context, self->expression.next); cp->expression.next = ast_type_copy(self->expression.node.context, self->expression.next);
} }
fromex = &self->expression; fromex = &self->expression;
selfex = &cp->expression; selfex = &cp->expression;
selfex->count = fromex->count; selfex->count = fromex->count;
selfex->flags = fromex->flags; selfex->flags = fromex->flags;
for (i = 0; i < vec_size(fromex->params); ++i) { for (auto &it : fromex->params) {
ast_value *v = ast_value_copy(fromex->params[i]); ast_value *v = ast_value_copy(it);
vec_push(selfex->params, v); selfex->params.push_back(v);
} }
return cp; return cp;
} }
void ast_type_adopt_impl(ast_expression *self, const ast_expression *other) void ast_type_adopt_impl(ast_expression *self, const ast_expression *other)
{ {
size_t i;
const ast_expression *fromex; const ast_expression *fromex;
ast_expression *selfex; ast_expression *selfex;
self->vtype = other->vtype; self->vtype = other->vtype;
if (other->next) { if (other->next) {
self->next = (ast_expression*)ast_type_copy(ast_ctx(self), other->next); self->next = (ast_expression*)ast_type_copy(ast_ctx(self), other->next);
} }
fromex = other; fromex = other;
selfex = self; selfex = self;
selfex->count = fromex->count; selfex->count = fromex->count;
selfex->flags = fromex->flags; selfex->flags = fromex->flags;
for (i = 0; i < vec_size(fromex->params); ++i) { for (auto &it : fromex->params) {
ast_value *v = ast_value_copy(fromex->params[i]); ast_value *v = ast_value_copy(it);
vec_push(selfex->params, v); selfex->params.push_back(v);
} }
} }
@ -167,7 +164,6 @@ static ast_expression* ast_shallow_type(lex_ctx_t ctx, int vtype)
ast_expression* ast_type_copy(lex_ctx_t ctx, const ast_expression *ex) ast_expression* ast_type_copy(lex_ctx_t ctx, const ast_expression *ex)
{ {
size_t i;
const ast_expression *fromex; const ast_expression *fromex;
ast_expression *selfex; ast_expression *selfex;
@ -190,11 +186,11 @@ ast_expression* ast_type_copy(lex_ctx_t ctx, const ast_expression *ex)
else else
selfex->next = NULL; selfex->next = NULL;
selfex->count = fromex->count; selfex->count = fromex->count;
selfex->flags = fromex->flags; selfex->flags = fromex->flags;
for (i = 0; i < vec_size(fromex->params); ++i) { for (auto &it : fromex->params) {
ast_value *v = ast_value_copy(fromex->params[i]); ast_value *v = ast_value_copy(it);
vec_push(selfex->params, v); selfex->params.push_back(v);
} }
return self; return self;
@ -210,16 +206,16 @@ bool ast_compare_type(ast_expression *a, ast_expression *b)
return false; return false;
if (!a->next != !b->next) if (!a->next != !b->next)
return false; return false;
if (vec_size(a->params) != vec_size(b->params)) if (a->params.size() != b->params.size())
return false; return false;
if ((a->flags & AST_FLAG_TYPE_MASK) != if ((a->flags & AST_FLAG_TYPE_MASK) !=
(b->flags & AST_FLAG_TYPE_MASK) ) (b->flags & AST_FLAG_TYPE_MASK) )
{ {
return false; return false;
} }
if (vec_size(a->params)) { if (a->params.size()) {
size_t i; size_t i;
for (i = 0; i < vec_size(a->params); ++i) { for (i = 0; i < a->params.size(); ++i) {
if (!ast_compare_type((ast_expression*)a->params[i], if (!ast_compare_type((ast_expression*)a->params[i],
(ast_expression*)b->params[i])) (ast_expression*)b->params[i]))
return false; return false;
@ -270,14 +266,14 @@ static size_t ast_type_to_string_impl(ast_expression *e, char *buf, size_t bufsi
pos = ast_type_to_string_impl(e->next, buf, bufsize, pos); pos = ast_type_to_string_impl(e->next, buf, bufsize, pos);
if (pos + 2 >= bufsize) if (pos + 2 >= bufsize)
goto full; goto full;
if (!vec_size(e->params)) { if (e->params.empty()) {
buf[pos++] = '('; buf[pos++] = '(';
buf[pos++] = ')'; buf[pos++] = ')';
return pos; return pos;
} }
buf[pos++] = '('; buf[pos++] = '(';
pos = ast_type_to_string_impl((ast_expression*)(e->params[0]), buf, bufsize, pos); pos = ast_type_to_string_impl((ast_expression*)(e->params[0]), buf, bufsize, pos);
for (i = 1; i < vec_size(e->params); ++i) { for (i = 1; i < e->params.size(); ++i) {
if (pos + 2 >= bufsize) if (pos + 2 >= bufsize)
goto full; goto full;
buf[pos++] = ','; buf[pos++] = ',';
@ -405,7 +401,7 @@ void ast_value_delete(ast_value* self)
void ast_value_params_add(ast_value *self, ast_value *p) void ast_value_params_add(ast_value *self, ast_value *p)
{ {
vec_push(self->expression.params, p); self->expression.params.push_back(p);
} }
bool ast_value_set_name(ast_value *self, const char *name) bool ast_value_set_name(ast_value *self, const char *name)
@ -908,7 +904,6 @@ ast_label* ast_label_new(lex_ctx_t ctx, const char *name, bool undefined)
self->name = util_strdup(name); self->name = util_strdup(name);
self->irblock = NULL; self->irblock = NULL;
self->gotos = NULL;
self->undefined = undefined; self->undefined = undefined;
return self; return self;
@ -917,14 +912,13 @@ ast_label* ast_label_new(lex_ctx_t ctx, const char *name, bool undefined)
void ast_label_delete(ast_label *self) void ast_label_delete(ast_label *self)
{ {
mem_d((void*)self->name); mem_d((void*)self->name);
vec_free(self->gotos);
ast_expression_delete((ast_expression*)self); ast_expression_delete((ast_expression*)self);
mem_d(self); mem_d(self);
} }
static void ast_label_register_goto(ast_label *self, ast_goto *g) static void ast_label_register_goto(ast_label *self, ast_goto *g)
{ {
vec_push(self->gotos, g); self->gotos.push_back(g);
} }
ast_goto* ast_goto_new(lex_ctx_t ctx, const char *name) ast_goto* ast_goto_new(lex_ctx_t ctx, const char *name)
@ -1058,11 +1052,11 @@ bool ast_call_check_types(ast_call *self, ast_expression *va_type)
char texp[1024]; char texp[1024];
char tgot[1024]; char tgot[1024];
size_t i; size_t i;
bool retval = true; bool retval = true;
const ast_expression *func = self->func; const ast_expression *func = self->func;
size_t count = vec_size(self->params); size_t count = vec_size(self->params);
if (count > vec_size(func->params)) if (count > func->params.size())
count = vec_size(func->params); count = func->params.size();
for (i = 0; i < count; ++i) { for (i = 0; i < count; ++i) {
if (ast_istype(self->params[i], ast_argpipe)) { if (ast_istype(self->params[i], ast_argpipe)) {
@ -1085,7 +1079,7 @@ bool ast_call_check_types(ast_call *self, ast_expression *va_type)
} }
} }
count = vec_size(self->params); count = vec_size(self->params);
if (count > vec_size(func->params) && func->varparam) { if (count > func->params.size() && func->varparam) {
for (; i < count; ++i) { for (; i < count; ++i) {
if (ast_istype(self->params[i], ast_argpipe)) { if (ast_istype(self->params[i], ast_argpipe)) {
/* warn about type safety instead */ /* warn about type safety instead */
@ -1140,18 +1134,13 @@ ast_block* ast_block_new(lex_ctx_t ctx)
ast_instantiate(ast_block, ctx, ast_block_delete); ast_instantiate(ast_block, ctx, ast_block_delete);
ast_expression_init((ast_expression*)self, ast_expression_init((ast_expression*)self,
(ast_expression_codegen*)&ast_block_codegen); (ast_expression_codegen*)&ast_block_codegen);
self->locals = NULL;
self->exprs = NULL;
self->collect = NULL;
return self; return self;
} }
bool ast_block_add_expr(ast_block *self, ast_expression *e) bool ast_block_add_expr(ast_block *self, ast_expression *e)
{ {
ast_propagate_effects(self, e); ast_propagate_effects(self, e);
vec_push(self->exprs, e); self->exprs.push_back(e);
if (self->expression.next) { if (self->expression.next) {
ast_delete(self->expression.next); ast_delete(self->expression.next);
self->expression.next = NULL; self->expression.next = NULL;
@ -1162,22 +1151,15 @@ bool ast_block_add_expr(ast_block *self, ast_expression *e)
void ast_block_collect(ast_block *self, ast_expression *expr) void ast_block_collect(ast_block *self, ast_expression *expr)
{ {
vec_push(self->collect, expr); self->collect.push_back(expr);
expr->node.keep = true; expr->node.keep = true;
} }
void ast_block_delete(ast_block *self) void ast_block_delete(ast_block *self)
{ {
size_t i; for (auto &it : self->exprs) ast_unref(it);
for (i = 0; i < vec_size(self->exprs); ++i) for (auto &it : self->locals) ast_delete(it);
ast_unref(self->exprs[i]); for (auto &it : self->collect) ast_delete(it);
vec_free(self->exprs);
for (i = 0; i < vec_size(self->locals); ++i)
ast_delete(self->locals[i]);
vec_free(self->locals);
for (i = 0; i < vec_size(self->collect); ++i)
ast_delete(self->collect[i]);
vec_free(self->collect);
ast_expression_delete((ast_expression*)self); ast_expression_delete((ast_expression*)self);
mem_d(self); mem_d(self);
} }
@ -1826,14 +1808,13 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir)
/* fill the parameter list */ /* fill the parameter list */
ec = &self->vtype->expression; ec = &self->vtype->expression;
for (i = 0; i < vec_size(ec->params); ++i) for (auto &it : ec->params) {
{ if (it->expression.vtype == TYPE_FIELD)
if (ec->params[i]->expression.vtype == TYPE_FIELD) vec_push(irf->params, it->expression.next->vtype);
vec_push(irf->params, ec->params[i]->expression.next->vtype);
else else
vec_push(irf->params, ec->params[i]->expression.vtype); vec_push(irf->params, it->expression.vtype);
if (!self->builtin) { if (!self->builtin) {
if (!ast_local_codegen(ec->params[i], self->ir_func, true)) if (!ast_local_codegen(it, self->ir_func, true))
return false; return false;
} }
} }
@ -1943,8 +1924,6 @@ static bool starts_a_label(ast_expression *ex)
*/ */
bool ast_block_codegen(ast_block *self, ast_function *func, bool lvalue, ir_value **out) bool ast_block_codegen(ast_block *self, ast_function *func, bool lvalue, ir_value **out)
{ {
size_t i;
/* We don't use this /* We don't use this
* Note: an ast-representation using the comma-operator * Note: an ast-representation using the comma-operator
* of the form: (a, b, c) = x should not assign to c... * of the form: (a, b, c) = x should not assign to c...
@ -1968,25 +1947,23 @@ bool ast_block_codegen(ast_block *self, ast_function *func, bool lvalue, ir_valu
*out = NULL; *out = NULL;
/* generate locals */ /* generate locals */
for (i = 0; i < vec_size(self->locals); ++i) for (auto &it : self->locals) {
{ if (!ast_local_codegen(it, func->ir_func, false)) {
if (!ast_local_codegen(self->locals[i], func->ir_func, false)) {
if (OPTS_OPTION_BOOL(OPTION_DEBUG)) if (OPTS_OPTION_BOOL(OPTION_DEBUG))
compile_error(ast_ctx(self), "failed to generate local `%s`", self->locals[i]->name); compile_error(ast_ctx(self), "failed to generate local `%s`", it->name);
return false; return false;
} }
} }
for (i = 0; i < vec_size(self->exprs); ++i) for (auto &it : self->exprs) {
{
ast_expression_codegen *gen; ast_expression_codegen *gen;
if (func->curblock->final && !starts_a_label(self->exprs[i])) { if (func->curblock->final && !starts_a_label(it)) {
if (compile_warning(ast_ctx(self->exprs[i]), WARN_UNREACHABLE_CODE, "unreachable statement")) if (compile_warning(ast_ctx(it), WARN_UNREACHABLE_CODE, "unreachable statement"))
return false; return false;
continue; continue;
} }
gen = self->exprs[i]->codegen; gen = it->codegen;
if (!(*gen)(self->exprs[i], func, false, out)) if (!(*gen)(it, func, false, out))
return false; return false;
} }
@ -3271,7 +3248,6 @@ bool ast_switch_codegen(ast_switch *self, ast_function *func, bool lvalue, ir_va
bool ast_label_codegen(ast_label *self, ast_function *func, bool lvalue, ir_value **out) bool ast_label_codegen(ast_label *self, ast_function *func, bool lvalue, ir_value **out)
{ {
size_t i;
ir_value *dummy; ir_value *dummy;
if (self->undefined) { if (self->undefined) {
@ -3300,8 +3276,8 @@ bool ast_label_codegen(ast_label *self, ast_function *func, bool lvalue, ir_valu
func->curblock = self->irblock; func->curblock = self->irblock;
/* Generate all the leftover gotos */ /* Generate all the leftover gotos */
for (i = 0; i < vec_size(self->gotos); ++i) { for (auto &it : self->gotos) {
if (!ast_goto_codegen(self->gotos[i], func, false, &dummy)) if (!ast_goto_codegen(it, func, false, &dummy))
return false; return false;
} }

226
ast.h
View file

@ -1,5 +1,6 @@
#ifndef GMQCC_AST_HDR #ifndef GMQCC_AST_HDR
#define GMQCC_AST_HDR #define GMQCC_AST_HDR
#include <vector>
#include "ir.h" #include "ir.h"
typedef uint16_t ast_flag_t; typedef uint16_t ast_flag_t;
@ -8,30 +9,29 @@ typedef uint16_t ast_flag_t;
* "main" ast node types for now. * "main" ast node types for now.
*/ */
typedef struct ast_node_common ast_node; struct ast_node;
typedef struct ast_expression_common ast_expression; struct ast_expression;
struct ast_value;
typedef struct ast_value_s ast_value; struct ast_function;
typedef struct ast_function_s ast_function; struct ast_block;
typedef struct ast_block_s ast_block; struct ast_binary;
typedef struct ast_binary_s ast_binary; struct ast_store;
typedef struct ast_store_s ast_store; struct ast_binstore;
typedef struct ast_binstore_s ast_binstore; struct ast_entfield;
typedef struct ast_entfield_s ast_entfield; struct ast_ifthen;
typedef struct ast_ifthen_s ast_ifthen; struct ast_ternary;
typedef struct ast_ternary_s ast_ternary; struct ast_loop;
typedef struct ast_loop_s ast_loop; struct ast_call;
typedef struct ast_call_s ast_call; struct ast_unary;
typedef struct ast_unary_s ast_unary; struct ast_return;
typedef struct ast_return_s ast_return; struct ast_member;
typedef struct ast_member_s ast_member; struct ast_array_index;
typedef struct ast_array_index_s ast_array_index; struct ast_breakcont;
typedef struct ast_breakcont_s ast_breakcont; struct ast_switch;
typedef struct ast_switch_s ast_switch; struct ast_label;
typedef struct ast_label_s ast_label; struct ast_goto;
typedef struct ast_goto_s ast_goto; struct ast_argpipe;
typedef struct ast_argpipe_s ast_argpipe; struct ast_state;
typedef struct ast_state_s ast_state;
enum { enum {
AST_FLAG_VARIADIC = 1 << 0, AST_FLAG_VARIADIC = 1 << 0,
@ -100,9 +100,10 @@ enum {
/* Node interface with common components /* Node interface with common components
*/ */
typedef void ast_node_delete(ast_node*); typedef void ast_node_delete(ast_node*);
struct ast_node_common
struct ast_node
{ {
lex_ctx_t context; lex_ctx_t context;
/* I don't feel comfortable using keywords like 'delete' as names... */ /* I don't feel comfortable using keywords like 'delete' as names... */
ast_node_delete *destroy; ast_node_delete *destroy;
int nodetype; int nodetype;
@ -140,15 +141,17 @@ typedef bool ast_expression_codegen(ast_expression*,
* type `expression`, so the ast_ident's codegen would search for * type `expression`, so the ast_ident's codegen would search for
* variables through the environment (or functions, constants...). * variables through the environment (or functions, constants...).
*/ */
struct ast_expression_common struct ast_expression {
{ ast_expression() {}
ast_node node; ast_node node;
ast_expression_codegen *codegen; ast_expression_codegen *codegen;
int vtype; int vtype;
ast_expression *next; ast_expression *next;
/* arrays get a member-count */ /* arrays get a member-count */
size_t count; size_t count;
ast_value* *params; std::vector<ast_value*> params;
ast_flag_t flags; ast_flag_t flags;
/* void foo(string...) gets varparam set as a restriction /* void foo(string...) gets varparam set as a restriction
* for variadic parameters * for variadic parameters
@ -170,7 +173,7 @@ struct ast_expression_common
* typedef float foo; * typedef float foo;
* is like creating a 'float foo', foo serving as the type's name. * is like creating a 'float foo', foo serving as the type's name.
*/ */
typedef union { union basic_value_t {
qcfloat_t vfloat; qcfloat_t vfloat;
int vint; int vint;
vec3_t vvec; vec3_t vvec;
@ -178,18 +181,18 @@ typedef union {
int ventity; int ventity;
ast_function *vfunc; ast_function *vfunc;
ast_value *vfield; ast_value *vfield;
} basic_value_t; };
struct ast_value_s struct ast_value
{ {
ast_expression expression; ast_expression expression;
const char *name; const char *name;
const char *desc; const char *desc;
const char *argcounter; const char *argcounter;
int cvq; /* const/var qualifier */ int cvq; /* const/var qualifier */
bool isfield; /* this declares a field */ bool isfield; /* this declares a field */
bool isimm; /* an immediate, not just const */ bool isimm; /* an immediate, not just const */
bool hasvalue; bool hasvalue;
@ -206,14 +209,14 @@ struct ast_value_s
ir_value *ir_v; ir_value *ir_v;
ir_value **ir_values; ir_value **ir_values;
size_t ir_value_count; size_t ir_value_count;
/* ONLY for arrays in progs version up to 6 */ /* ONLY for arrays in progs version up to 6 */
ast_value *setter; ast_value *setter;
ast_value *getter; ast_value *getter;
bool intrinsic; /* true if associated with intrinsic */ bool intrinsic; /* true if associated with intrinsic */
}; };
ast_value* ast_value_new(lex_ctx_t ctx, const char *name, int qctype); ast_value* ast_value_new(lex_ctx_t ctx, const char *name, int qctype);
@ -238,27 +241,26 @@ ast_expression* ast_type_copy(lex_ctx_t ctx, const ast_expression *ex);
void ast_type_adopt_impl(ast_expression *self, const ast_expression *other); void ast_type_adopt_impl(ast_expression *self, const ast_expression *other);
void ast_type_to_string(ast_expression *e, char *buf, size_t bufsize); void ast_type_to_string(ast_expression *e, char *buf, size_t bufsize);
typedef enum ast_binary_ref_s { enum ast_binary_ref {
AST_REF_NONE = 0, AST_REF_NONE = 0,
AST_REF_LEFT = 1 << 1, AST_REF_LEFT = 1 << 1,
AST_REF_RIGHT = 1 << 2, AST_REF_RIGHT = 1 << 2,
AST_REF_ALL = (AST_REF_LEFT | AST_REF_RIGHT) AST_REF_ALL = (AST_REF_LEFT | AST_REF_RIGHT)
} ast_binary_ref; };
/* Binary /* Binary
* *
* A value-returning binary expression. * A value-returning binary expression.
*/ */
struct ast_binary_s struct ast_binary
{ {
ast_expression expression; ast_expression expression;
int op;
int op;
ast_expression *left; ast_expression *left;
ast_expression *right; ast_expression *right;
ast_binary_ref refs; ast_binary_ref refs;
bool right_first; bool right_first;
}; };
ast_binary* ast_binary_new(lex_ctx_t ctx, ast_binary* ast_binary_new(lex_ctx_t ctx,
int op, int op,
@ -270,16 +272,15 @@ ast_binary* ast_binary_new(lex_ctx_t ctx,
* An assignment including a binary expression with the source as left operand. * An assignment including a binary expression with the source as left operand.
* Eg. a += b; is a binstore { INSTR_STORE, INSTR_ADD, a, b } * Eg. a += b; is a binstore { INSTR_STORE, INSTR_ADD, a, b }
*/ */
struct ast_binstore_s struct ast_binstore
{ {
ast_expression expression; ast_expression expression;
int opstore;
int opstore; int opbin;
int opbin;
ast_expression *dest; ast_expression *dest;
ast_expression *source; ast_expression *source;
/* for &~= which uses the destination in a binary in source we can use this */ /* for &~= which uses the destination in a binary in source we can use this */
bool keep_dest; bool keep_dest;
}; };
ast_binstore* ast_binstore_new(lex_ctx_t ctx, ast_binstore* ast_binstore_new(lex_ctx_t ctx,
int storeop, int storeop,
@ -291,15 +292,14 @@ ast_binstore* ast_binstore_new(lex_ctx_t ctx,
* *
* Regular unary expressions: not,neg * Regular unary expressions: not,neg
*/ */
struct ast_unary_s struct ast_unary
{ {
ast_expression expression; ast_expression expression;
int op;
int op;
ast_expression *operand; ast_expression *operand;
}; };
ast_unary* ast_unary_new(lex_ctx_t ctx, ast_unary* ast_unary_new(lex_ctx_t ctx,
int op, int op,
ast_expression *expr); ast_expression *expr);
/* Return /* Return
@ -308,12 +308,12 @@ ast_unary* ast_unary_new(lex_ctx_t ctx,
* will refuse to create further instructions. * will refuse to create further instructions.
* This should be honored by the parser. * This should be honored by the parser.
*/ */
struct ast_return_s struct ast_return
{ {
ast_expression expression; ast_expression expression;
ast_expression *operand; ast_expression *operand;
}; };
ast_return* ast_return_new(lex_ctx_t ctx, ast_return* ast_return_new(lex_ctx_t ctx,
ast_expression *expr); ast_expression *expr);
/* Entity-field /* Entity-field
@ -329,9 +329,9 @@ ast_return* ast_return_new(lex_ctx_t ctx,
* For this we will have to extend the codegen() functions with * For this we will have to extend the codegen() functions with
* a flag saying whether or not we need an L or an R-value. * a flag saying whether or not we need an L or an R-value.
*/ */
struct ast_entfield_s struct ast_entfield
{ {
ast_expression expression; ast_expression expression;
/* The entity can come from an expression of course. */ /* The entity can come from an expression of course. */
ast_expression *entity; ast_expression *entity;
/* As can the field, it just must result in a value of TYPE_FIELD */ /* As can the field, it just must result in a value of TYPE_FIELD */
@ -345,13 +345,13 @@ ast_entfield* ast_entfield_new_force(lex_ctx_t ctx, ast_expression *entity, ast_
* For now used for vectors. If we get structs or unions * For now used for vectors. If we get structs or unions
* we can have them handled here as well. * we can have them handled here as well.
*/ */
struct ast_member_s struct ast_member
{ {
ast_expression expression; ast_expression expression;
ast_expression *owner; ast_expression *owner;
unsigned int field; unsigned int field;
const char *name; const char *name;
bool rvalue; bool rvalue;
}; };
ast_member* ast_member_new(lex_ctx_t ctx, ast_expression *owner, unsigned int field, const char *name); ast_member* ast_member_new(lex_ctx_t ctx, ast_expression *owner, unsigned int field, const char *name);
void ast_member_delete(ast_member*); void ast_member_delete(ast_member*);
@ -368,9 +368,9 @@ bool ast_member_set_name(ast_member*, const char *name);
* In any case, accessing an element via a compiletime-constant index will * In any case, accessing an element via a compiletime-constant index will
* result in quick access to that variable. * result in quick access to that variable.
*/ */
struct ast_array_index_s struct ast_array_index
{ {
ast_expression expression; ast_expression expression;
ast_expression *array; ast_expression *array;
ast_expression *index; ast_expression *index;
}; };
@ -380,9 +380,9 @@ ast_array_index* ast_array_index_new(lex_ctx_t ctx, ast_expression *array, ast_e
* *
* copy all varargs starting from a specific index * copy all varargs starting from a specific index
*/ */
struct ast_argpipe_s struct ast_argpipe
{ {
ast_expression expression; ast_expression expression;
ast_expression *index; ast_expression *index;
}; };
ast_argpipe* ast_argpipe_new(lex_ctx_t ctx, ast_expression *index); ast_argpipe* ast_argpipe_new(lex_ctx_t ctx, ast_expression *index);
@ -392,10 +392,10 @@ ast_argpipe* ast_argpipe_new(lex_ctx_t ctx, ast_expression *index);
* Stores left<-right and returns left. * Stores left<-right and returns left.
* Specialized binary expression node * Specialized binary expression node
*/ */
struct ast_store_s struct ast_store
{ {
ast_expression expression; ast_expression expression;
int op; int op;
ast_expression *dest; ast_expression *dest;
ast_expression *source; ast_expression *source;
}; };
@ -413,9 +413,9 @@ ast_store* ast_store_new(lex_ctx_t ctx, int op,
* output field though. For ternary expressions an ast_ternary will be * output field though. For ternary expressions an ast_ternary will be
* added. * added.
*/ */
struct ast_ifthen_s struct ast_ifthen
{ {
ast_expression expression; ast_expression expression;
ast_expression *cond; ast_expression *cond;
/* It's all just 'expressions', since an ast_block is one too. */ /* It's all just 'expressions', since an ast_block is one too. */
ast_expression *on_true; ast_expression *on_true;
@ -436,9 +436,9 @@ ast_ifthen* ast_ifthen_new(lex_ctx_t ctx, ast_expression *cond, ast_expression *
* This is the only ast_node beside ast_value which contains * This is the only ast_node beside ast_value which contains
* an ir_value. Theoretically we don't need to remember it though. * an ir_value. Theoretically we don't need to remember it though.
*/ */
struct ast_ternary_s struct ast_ternary
{ {
ast_expression expression; ast_expression expression;
ast_expression *cond; ast_expression *cond;
/* It's all just 'expressions', since an ast_block is one too. */ /* It's all just 'expressions', since an ast_block is one too. */
ast_expression *on_true; ast_expression *on_true;
@ -469,9 +469,9 @@ continue: // a 'continue' will jump here
{inc}; {inc};
} }
*/ */
struct ast_loop_s struct ast_loop
{ {
ast_expression expression; ast_expression expression;
ast_expression *initexpr; ast_expression *initexpr;
ast_expression *precond; ast_expression *precond;
ast_expression *postcond; ast_expression *postcond;
@ -495,11 +495,11 @@ ast_loop* ast_loop_new(lex_ctx_t ctx,
/* Break/Continue /* Break/Continue
*/ */
struct ast_breakcont_s struct ast_breakcont
{ {
ast_expression expression; ast_expression expression;
bool is_continue; bool is_continue;
unsigned int levels; unsigned int levels;
}; };
ast_breakcont* ast_breakcont_new(lex_ctx_t ctx, bool iscont, unsigned int levels); ast_breakcont* ast_breakcont_new(lex_ctx_t ctx, bool iscont, unsigned int levels);
@ -513,15 +513,15 @@ ast_breakcont* ast_breakcont_new(lex_ctx_t ctx, bool iscont, unsigned int levels
* be expected from it. * be expected from it.
* TODO: Ticket #20 * TODO: Ticket #20
*/ */
typedef struct { struct ast_switch_case {
ast_expression *value; /* #20 will replace this */ ast_expression *value; /* #20 will replace this */
ast_expression *code; ast_expression *code;
} ast_switch_case; };
struct ast_switch_s
{
ast_expression expression;
ast_expression *operand; struct ast_switch
{
ast_expression expression;
ast_expression *operand;
ast_switch_case *cases; ast_switch_case *cases;
}; };
@ -531,15 +531,15 @@ ast_switch* ast_switch_new(lex_ctx_t ctx, ast_expression *op);
* *
* Introduce a label which can be used together with 'goto' * Introduce a label which can be used together with 'goto'
*/ */
struct ast_label_s struct ast_label
{ {
ast_expression expression; ast_expression expression;
const char *name; const char *name;
ir_block *irblock; ir_block *irblock;
ast_goto **gotos; std::vector<ast_goto*> gotos;
/* means it has not yet been defined */ /* means it has not yet been defined */
bool undefined; bool undefined;
}; };
ast_label* ast_label_new(lex_ctx_t ctx, const char *name, bool undefined); ast_label* ast_label_new(lex_ctx_t ctx, const char *name, bool undefined);
@ -548,12 +548,12 @@ ast_label* ast_label_new(lex_ctx_t ctx, const char *name, bool undefined);
* *
* Go to a label, the label node is filled in at a later point! * Go to a label, the label node is filled in at a later point!
*/ */
struct ast_goto_s struct ast_goto
{ {
ast_expression expression; ast_expression expression;
const char *name; const char *name;
ast_label *target; ast_label *target;
ir_block *irblock_from; ir_block *irblock_from;
}; };
ast_goto* ast_goto_new(lex_ctx_t ctx, const char *name); ast_goto* ast_goto_new(lex_ctx_t ctx, const char *name);
@ -563,9 +563,9 @@ void ast_goto_set_label(ast_goto*, ast_label*);
* *
* For frame/think state updates: void foo() [framenum, nextthink] {} * For frame/think state updates: void foo() [framenum, nextthink] {}
*/ */
struct ast_state_s struct ast_state
{ {
ast_expression expression; ast_expression expression;
ast_expression *framenum; ast_expression *framenum;
ast_expression *nextthink; ast_expression *nextthink;
}; };
@ -582,9 +582,9 @@ void ast_state_delete(ast_state*);
* Additionally it contains a list of ast_expressions as parameters. * Additionally it contains a list of ast_expressions as parameters.
* Since calls can return values, an ast_call is also an ast_expression. * Since calls can return values, an ast_call is also an ast_expression.
*/ */
struct ast_call_s struct ast_call
{ {
ast_expression expression; ast_expression expression;
ast_expression *func; ast_expression *func;
ast_expression **params; ast_expression **params;
ast_expression *va_count; ast_expression *va_count;
@ -596,13 +596,13 @@ bool ast_call_check_types(ast_call*, ast_expression *this_func_va_type);
/* Blocks /* Blocks
* *
*/ */
struct ast_block_s struct ast_block
{ {
ast_expression expression; ast_expression expression;
ast_value* *locals; std::vector<ast_value*> locals;
ast_expression* *exprs; std::vector<ast_expression*> exprs;
ast_expression* *collect; std::vector<ast_expression*> collect;
}; };
ast_block* ast_block_new(lex_ctx_t ctx); ast_block* ast_block_new(lex_ctx_t ctx);
void ast_block_delete(ast_block*); void ast_block_delete(ast_block*);
@ -621,7 +621,7 @@ bool GMQCC_WARN ast_block_add_expr(ast_block*, ast_expression*);
* pointers could just work with a name. However, this way could be * pointers could just work with a name. However, this way could be
* more flexible, and adds no real complexity. * more flexible, and adds no real complexity.
*/ */
struct ast_function_s struct ast_function
{ {
ast_node node; ast_node node;
@ -649,13 +649,11 @@ struct ast_function_s
* here to use in ast_function_label. * here to use in ast_function_label.
*/ */
char labelbuf[64]; char labelbuf[64];
ast_block* *blocks; ast_block* *blocks;
ast_value *varargs;
ast_value *varargs; ast_value *argc;
ast_value *argc; ast_value *fixedparams;
ast_value *fixedparams; ast_value *return_value;
ast_value *return_value;
}; };
ast_function* ast_function_new(lex_ctx_t ctx, const char *name, ast_value *vtype); ast_function* ast_function_new(lex_ctx_t ctx, const char *name, ast_value *vtype);
/* This will NOT delete the underlying ast_value */ /* This will NOT delete the underlying ast_value */

View file

@ -24,7 +24,7 @@ static GMQCC_INLINE ast_function *intrin_value(intrin_t *intrin, ast_value **out
static GMQCC_INLINE void intrin_reg(intrin_t *intrin, ast_value *const value, ast_function *const func) { static GMQCC_INLINE void intrin_reg(intrin_t *intrin, ast_value *const value, ast_function *const func) {
vec_push(intrin->parser->functions, func); vec_push(intrin->parser->functions, func);
vec_push(intrin->parser->globals, (ast_expression*)value); vec_push(intrin->parser->globals, (ast_expression*)value);
} }
#define QC_POW_EPSILON 0.00001f #define QC_POW_EPSILON 0.00001f
@ -60,7 +60,7 @@ static ast_expression *intrin_isfinite(intrin_t *intrin) {
ast_block *block = ast_block_new(intrin_ctx(intrin)); ast_block *block = ast_block_new(intrin_ctx(intrin));
/* float x; */ /* float x; */
vec_push(value->expression.params, x); value->expression.params.push_back(x);
/* <callisnan> = isnan(x); */ /* <callisnan> = isnan(x); */
vec_push(callisnan->params, (ast_expression*)x); vec_push(callisnan->params, (ast_expression*)x);
@ -69,7 +69,7 @@ static ast_expression *intrin_isfinite(intrin_t *intrin) {
vec_push(callisinf->params, (ast_expression*)x); vec_push(callisinf->params, (ast_expression*)x);
/* return (!<callisnan> || <callisinf>); */ /* return (!<callisnan> || <callisinf>); */
vec_push(block->exprs, block->exprs.push_back(
(ast_expression*)ast_return_new( (ast_expression*)ast_return_new(
intrin_ctx(intrin), intrin_ctx(intrin),
(ast_expression*)ast_unary_new( (ast_expression*)ast_unary_new(
@ -102,7 +102,7 @@ static ast_expression *intrin_isinf(intrin_t *intrin) {
ast_block *body = ast_block_new(intrin_ctx(intrin)); ast_block *body = ast_block_new(intrin_ctx(intrin));
ast_function *func = intrin_value(intrin, &value, "isinf", TYPE_FLOAT); ast_function *func = intrin_value(intrin, &value, "isinf", TYPE_FLOAT);
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_return_new( (ast_expression*)ast_return_new(
intrin_ctx(intrin), intrin_ctx(intrin),
(ast_expression*)ast_binary_new( (ast_expression*)ast_binary_new(
@ -129,7 +129,7 @@ static ast_expression *intrin_isinf(intrin_t *intrin) {
) )
); );
vec_push(value->expression.params, x); value->expression.params.push_back(x);
vec_push(func->blocks, body); vec_push(func->blocks, body);
intrin_reg(intrin, value, func); intrin_reg(intrin, value, func);
@ -152,8 +152,8 @@ static ast_expression *intrin_isnan(intrin_t *intrin) {
ast_block *body = ast_block_new(intrin_ctx(intrin)); ast_block *body = ast_block_new(intrin_ctx(intrin));
ast_function *func = intrin_value(intrin, &value, "isnan", TYPE_FLOAT); ast_function *func = intrin_value(intrin, &value, "isnan", TYPE_FLOAT);
vec_push(body->locals, local); body->locals.push_back(local);
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -162,7 +162,7 @@ static ast_expression *intrin_isnan(intrin_t *intrin) {
) )
); );
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_return_new( (ast_expression*)ast_return_new(
intrin_ctx(intrin), intrin_ctx(intrin),
(ast_expression*)ast_binary_new( (ast_expression*)ast_binary_new(
@ -174,7 +174,7 @@ static ast_expression *intrin_isnan(intrin_t *intrin) {
) )
); );
vec_push(value->expression.params, arg1); value->expression.params.push_back(arg1);
vec_push(func->blocks, body); vec_push(func->blocks, body);
intrin_reg(intrin, value, func); intrin_reg(intrin, value, func);
@ -194,11 +194,11 @@ static ast_expression *intrin_isnormal(intrin_t *intrin) {
ast_block *body = ast_block_new(intrin_ctx(intrin)); ast_block *body = ast_block_new(intrin_ctx(intrin));
ast_function *func = intrin_value(intrin, &value, "isnormal", TYPE_FLOAT); ast_function *func = intrin_value(intrin, &value, "isnormal", TYPE_FLOAT);
vec_push(value->expression.params, x); value->expression.params.push_back(x);
vec_push(callisfinite->params, (ast_expression*)x); vec_push(callisfinite->params, (ast_expression*)x);
/* return <callisfinite> */ /* return <callisfinite> */
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_return_new( (ast_expression*)ast_return_new(
intrin_ctx(intrin), intrin_ctx(intrin),
(ast_expression*)callisfinite (ast_expression*)callisfinite
@ -221,10 +221,10 @@ static ast_expression *intrin_signbit(intrin_t *intrin) {
ast_block *body = ast_block_new(intrin_ctx(intrin)); ast_block *body = ast_block_new(intrin_ctx(intrin));
ast_function *func = intrin_value(intrin, &value, "signbit", TYPE_FLOAT); ast_function *func = intrin_value(intrin, &value, "signbit", TYPE_FLOAT);
vec_push(value->expression.params, x); value->expression.params.push_back(x);
/* return (x < 0); */ /* return (x < 0); */
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_return_new( (ast_expression*)ast_return_new(
intrin_ctx(intrin), intrin_ctx(intrin),
(ast_expression*)ast_ternary_new( (ast_expression*)ast_ternary_new(
@ -259,7 +259,7 @@ static ast_expression *intrin_acosh(intrin_t *intrin) {
ast_block *body = ast_block_new(intrin_ctx(intrin)); ast_block *body = ast_block_new(intrin_ctx(intrin));
ast_function *func = intrin_value(intrin, &value, "acosh", TYPE_FLOAT); ast_function *func = intrin_value(intrin, &value, "acosh", TYPE_FLOAT);
vec_push(value->expression.params, x); value->expression.params.push_back(x);
/* <callsqrt> = sqrt((x * x) - 1); */ /* <callsqrt> = sqrt((x * x) - 1); */
vec_push(callsqrt->params, vec_push(callsqrt->params,
@ -287,7 +287,7 @@ static ast_expression *intrin_acosh(intrin_t *intrin) {
); );
/* return <calllog>; */ /* return <calllog>; */
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_return_new( (ast_expression*)ast_return_new(
intrin_ctx(intrin), intrin_ctx(intrin),
(ast_expression*)calllog (ast_expression*)calllog
@ -312,7 +312,7 @@ static ast_expression *intrin_asinh(intrin_t *intrin) {
ast_block *body = ast_block_new(intrin_ctx(intrin)); ast_block *body = ast_block_new(intrin_ctx(intrin));
ast_function *func = intrin_value(intrin, &value, "asinh", TYPE_FLOAT); ast_function *func = intrin_value(intrin, &value, "asinh", TYPE_FLOAT);
vec_push(value->expression.params, x); value->expression.params.push_back(x);
/* <callsqrt> = sqrt((x * x) + 1); */ /* <callsqrt> = sqrt((x * x) + 1); */
vec_push(callsqrt->params, vec_push(callsqrt->params,
@ -340,7 +340,7 @@ static ast_expression *intrin_asinh(intrin_t *intrin) {
); );
/* return <calllog>; */ /* return <calllog>; */
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_return_new( (ast_expression*)ast_return_new(
intrin_ctx(intrin), intrin_ctx(intrin),
(ast_expression*)calllog (ast_expression*)calllog
@ -364,7 +364,7 @@ static ast_expression *intrin_atanh(intrin_t *intrin) {
ast_block *body = ast_block_new(intrin_ctx(intrin)); ast_block *body = ast_block_new(intrin_ctx(intrin));
ast_function *func = intrin_value(intrin, &value, "atanh", TYPE_FLOAT); ast_function *func = intrin_value(intrin, &value, "atanh", TYPE_FLOAT);
vec_push(value->expression.params, x); value->expression.params.push_back(x);
/* <callog> = log((1 + x) / (1 - x)); */ /* <callog> = log((1 + x) / (1 - x)); */
vec_push(calllog->params, vec_push(calllog->params,
@ -387,7 +387,7 @@ static ast_expression *intrin_atanh(intrin_t *intrin) {
); );
/* return 0.5 * <calllog>; */ /* return 0.5 * <calllog>; */
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_binary_new( (ast_expression*)ast_binary_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_MUL_F, INSTR_MUL_F,
@ -421,13 +421,14 @@ static ast_expression *intrin_exp(intrin_t *intrin) {
ast_block *body = ast_block_new(intrin_ctx(intrin)); ast_block *body = ast_block_new(intrin_ctx(intrin));
ast_function *func = intrin_value(intrin, &value, "exp", TYPE_FLOAT); ast_function *func = intrin_value(intrin, &value, "exp", TYPE_FLOAT);
vec_push(value->expression.params, x); value->expression.params.push_back(x);
vec_push(body->locals, sum);
vec_push(body->locals, acc); body->locals.push_back(sum);
vec_push(body->locals, i); body->locals.push_back(acc);
body->locals.push_back(i);
/* sum = 1.0; */ /* sum = 1.0; */
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -437,7 +438,7 @@ static ast_expression *intrin_exp(intrin_t *intrin) {
); );
/* acc = 1.0; */ /* acc = 1.0; */
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -450,7 +451,7 @@ static ast_expression *intrin_exp(intrin_t *intrin) {
* for (i = 1; i < 200; ++i) * for (i = 1; i < 200; ++i)
* sum += (acc *= x / i); * sum += (acc *= x / i);
*/ */
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_loop_new( (ast_expression*)ast_loop_new(
intrin_ctx(intrin), intrin_ctx(intrin),
/* i = 1; */ /* i = 1; */
@ -501,7 +502,7 @@ static ast_expression *intrin_exp(intrin_t *intrin) {
); );
/* return sum; */ /* return sum; */
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_return_new( (ast_expression*)ast_return_new(
intrin_ctx(intrin), intrin_ctx(intrin),
(ast_expression*)sum (ast_expression*)sum
@ -526,13 +527,13 @@ static ast_expression *intrin_exp2(intrin_t *intrin) {
ast_block *body = ast_block_new(intrin_ctx(intrin)); ast_block *body = ast_block_new(intrin_ctx(intrin));
ast_function *func = intrin_value(intrin, &value, "exp2", TYPE_FLOAT); ast_function *func = intrin_value(intrin, &value, "exp2", TYPE_FLOAT);
vec_push(value->expression.params, arg1); value->expression.params.push_back(arg1);
vec_push(callpow->params, (ast_expression*)intrin->fold->imm_float[3]); vec_push(callpow->params, (ast_expression*)intrin->fold->imm_float[3]);
vec_push(callpow->params, (ast_expression*)arg1); vec_push(callpow->params, (ast_expression*)arg1);
/* return <callpow> */ /* return <callpow> */
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_return_new( (ast_expression*)ast_return_new(
intrin_ctx(intrin), intrin_ctx(intrin),
(ast_expression*)callpow (ast_expression*)callpow
@ -557,13 +558,13 @@ static ast_expression *intrin_expm1(intrin_t *intrin) {
ast_block *body = ast_block_new(intrin_ctx(intrin)); ast_block *body = ast_block_new(intrin_ctx(intrin));
ast_function *func = intrin_value(intrin, &value, "expm1", TYPE_FLOAT); ast_function *func = intrin_value(intrin, &value, "expm1", TYPE_FLOAT);
vec_push(value->expression.params, x); value->expression.params.push_back(x);
/* <callexp> = exp(x); */ /* <callexp> = exp(x); */
vec_push(callexp->params, (ast_expression*)x); vec_push(callexp->params, (ast_expression*)x);
/* return <callexp> - 1; */ /* return <callexp> - 1; */
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_return_new( (ast_expression*)ast_return_new(
intrin_ctx(intrin), intrin_ctx(intrin),
(ast_expression*)ast_binary_new( (ast_expression*)ast_binary_new(
@ -658,21 +659,21 @@ static ast_expression *intrin_pow(intrin_t *intrin) {
ast_value *square = ast_value_new(intrin_ctx(intrin), "square", TYPE_FLOAT); ast_value *square = ast_value_new(intrin_ctx(intrin), "square", TYPE_FLOAT);
ast_value *accumulate = ast_value_new(intrin_ctx(intrin), "accumulate", TYPE_FLOAT); ast_value *accumulate = ast_value_new(intrin_ctx(intrin), "accumulate", TYPE_FLOAT);
ast_value *mid = ast_value_new(intrin_ctx(intrin), "mid", TYPE_FLOAT); ast_value *mid = ast_value_new(intrin_ctx(intrin), "mid", TYPE_FLOAT);
vec_push(body->locals, result); body->locals.push_back(result);
vec_push(body->locals, low); body->locals.push_back(low);
vec_push(body->locals, high); body->locals.push_back(high);
vec_push(body->locals, square); body->locals.push_back(square);
vec_push(body->locals, accumulate); body->locals.push_back(accumulate);
vec_push(body->locals, mid); body->locals.push_back(mid);
vec_push(value->expression.params, base); value->expression.params.push_back(base);
vec_push(value->expression.params, exp); value->expression.params.push_back(exp);
/* /*
* if (exp == 0.0) * if (exp == 0.0)
* return 1; * return 1;
*/ */
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_ifthen_new( (ast_expression*)ast_ifthen_new(
intrin_ctx(intrin), intrin_ctx(intrin),
(ast_expression*)ast_binary_new( (ast_expression*)ast_binary_new(
@ -693,7 +694,7 @@ static ast_expression *intrin_pow(intrin_t *intrin) {
* if (exp == 1.0) * if (exp == 1.0)
* return base; * return base;
*/ */
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_ifthen_new( (ast_expression*)ast_ifthen_new(
intrin_ctx(intrin), intrin_ctx(intrin),
(ast_expression*)ast_binary_new( (ast_expression*)ast_binary_new(
@ -724,7 +725,7 @@ static ast_expression *intrin_pow(intrin_t *intrin) {
* if (exp < 0) * if (exp < 0)
* return 1.0 / <callpow1>; * return 1.0 / <callpow1>;
*/ */
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_ifthen_new( (ast_expression*)ast_ifthen_new(
intrin_ctx(intrin), intrin_ctx(intrin),
(ast_expression*)ast_binary_new( (ast_expression*)ast_binary_new(
@ -763,7 +764,7 @@ static ast_expression *intrin_pow(intrin_t *intrin) {
* return result * result; * return result * result;
* } * }
*/ */
vec_push(expgt1->exprs, expgt1->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -771,7 +772,7 @@ static ast_expression *intrin_pow(intrin_t *intrin) {
(ast_expression*)callpow2 (ast_expression*)callpow2
) )
); );
vec_push(expgt1->exprs, expgt1->exprs.push_back(
(ast_expression*)ast_return_new( (ast_expression*)ast_return_new(
intrin_ctx(intrin), intrin_ctx(intrin),
(ast_expression*)ast_binary_new( (ast_expression*)ast_binary_new(
@ -788,7 +789,7 @@ static ast_expression *intrin_pow(intrin_t *intrin) {
* <expgt1> * <expgt1>
* } * }
*/ */
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_ifthen_new( (ast_expression*)ast_ifthen_new(
intrin_ctx(intrin), intrin_ctx(intrin),
(ast_expression*)ast_binary_new( (ast_expression*)ast_binary_new(
@ -814,14 +815,14 @@ static ast_expression *intrin_pow(intrin_t *intrin) {
* accumulate = square; * accumulate = square;
* mid = high / 2.0f; * mid = high / 2.0f;
*/ */
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_store_new(intrin_ctx(intrin), (ast_expression*)ast_store_new(intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
(ast_expression*)low, (ast_expression*)low,
(ast_expression*)intrin->fold->imm_float[0] (ast_expression*)intrin->fold->imm_float[0]
) )
); );
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -830,7 +831,7 @@ static ast_expression *intrin_pow(intrin_t *intrin) {
) )
); );
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -839,7 +840,7 @@ static ast_expression *intrin_pow(intrin_t *intrin) {
) )
); );
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -847,7 +848,7 @@ static ast_expression *intrin_pow(intrin_t *intrin) {
(ast_expression*)square (ast_expression*)square
) )
); );
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -867,7 +868,7 @@ static ast_expression *intrin_pow(intrin_t *intrin) {
* accumulate *= square; * accumulate *= square;
* } * }
*/ */
vec_push(midltexp->exprs, midltexp->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -875,7 +876,7 @@ static ast_expression *intrin_pow(intrin_t *intrin) {
(ast_expression*)mid (ast_expression*)mid
) )
); );
vec_push(midltexp->exprs, midltexp->exprs.push_back(
(ast_expression*)ast_binstore_new( (ast_expression*)ast_binstore_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -891,7 +892,7 @@ static ast_expression *intrin_pow(intrin_t *intrin) {
* accumulate *= (1.0 / square); * accumulate *= (1.0 / square);
* } * }
*/ */
vec_push(midltexpelse->exprs, midltexpelse->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -899,7 +900,7 @@ static ast_expression *intrin_pow(intrin_t *intrin) {
(ast_expression*)mid (ast_expression*)mid
) )
); );
vec_push(midltexpelse->exprs, midltexpelse->exprs.push_back(
(ast_expression*)ast_binstore_new( (ast_expression*)ast_binstore_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -930,7 +931,7 @@ static ast_expression *intrin_pow(intrin_t *intrin) {
* mid = (low + high) / 2; * mid = (low + high) / 2;
* } * }
*/ */
vec_push(whileblock->exprs, whileblock->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -938,7 +939,7 @@ static ast_expression *intrin_pow(intrin_t *intrin) {
(ast_expression*)callsqrt2 (ast_expression*)callsqrt2
) )
); );
vec_push(whileblock->exprs, whileblock->exprs.push_back(
(ast_expression*)ast_ifthen_new( (ast_expression*)ast_ifthen_new(
intrin_ctx(intrin), intrin_ctx(intrin),
(ast_expression*)ast_binary_new( (ast_expression*)ast_binary_new(
@ -951,7 +952,7 @@ static ast_expression *intrin_pow(intrin_t *intrin) {
(ast_expression*)midltexpelse (ast_expression*)midltexpelse
) )
); );
vec_push(whileblock->exprs, whileblock->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -986,7 +987,7 @@ static ast_expression *intrin_pow(intrin_t *intrin) {
* while (<callfabs> > epsilon) * while (<callfabs> > epsilon)
* <whileblock> * <whileblock>
*/ */
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_loop_new( (ast_expression*)ast_loop_new(
intrin_ctx(intrin), intrin_ctx(intrin),
/* init */ /* init */
@ -1012,7 +1013,7 @@ static ast_expression *intrin_pow(intrin_t *intrin) {
); );
/* return accumulate */ /* return accumulate */
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_return_new( (ast_expression*)ast_return_new(
intrin_ctx(intrin), intrin_ctx(intrin),
(ast_expression*)accumulate (ast_expression*)accumulate
@ -1043,14 +1044,14 @@ static ast_expression *intrin_mod(intrin_t *intrin) {
ast_block *body = ast_block_new(intrin_ctx(intrin)); ast_block *body = ast_block_new(intrin_ctx(intrin));
ast_function *func = intrin_value(intrin, &value, "mod", TYPE_FLOAT); ast_function *func = intrin_value(intrin, &value, "mod", TYPE_FLOAT);
vec_push(value->expression.params, a); value->expression.params.push_back(a);
vec_push(value->expression.params, b); value->expression.params.push_back(b);
vec_push(body->locals, div); body->locals.push_back(div);
vec_push(body->locals, sign); body->locals.push_back(sign);
/* div = a / b; */ /* div = a / b; */
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -1065,7 +1066,7 @@ static ast_expression *intrin_mod(intrin_t *intrin) {
); );
/* sign = (div < 0.0f) ? -1 : 1; */ /* sign = (div < 0.0f) ? -1 : 1; */
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -1095,7 +1096,7 @@ static ast_expression *intrin_mod(intrin_t *intrin) {
); );
/* return a - b * sign * <call> */ /* return a - b * sign * <call> */
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_return_new( (ast_expression*)ast_return_new(
intrin_ctx(intrin), intrin_ctx(intrin),
(ast_expression*)ast_binary_new( (ast_expression*)ast_binary_new(
@ -1134,7 +1135,7 @@ static ast_expression *intrin_fabs(intrin_t *intrin) {
ast_block *body = ast_block_new(intrin_ctx(intrin)); ast_block *body = ast_block_new(intrin_ctx(intrin));
ast_function *func = intrin_value(intrin, &value, "fabs", TYPE_FLOAT); ast_function *func = intrin_value(intrin, &value, "fabs", TYPE_FLOAT);
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_return_new( (ast_expression*)ast_return_new(
intrin_ctx(intrin), intrin_ctx(intrin),
(ast_expression*)ast_ternary_new( (ast_expression*)ast_ternary_new(
@ -1155,7 +1156,8 @@ static ast_expression *intrin_fabs(intrin_t *intrin) {
) )
); );
vec_push(value->expression.params, arg1); value->expression.params.push_back(arg1);
vec_push(func->blocks, body); vec_push(func->blocks, body);
intrin_reg(intrin, value, func); intrin_reg(intrin, value, func);
@ -1176,10 +1178,10 @@ static ast_expression *intrin_epsilon(intrin_t *intrin) {
ast_block *body = ast_block_new(intrin_ctx(intrin)); ast_block *body = ast_block_new(intrin_ctx(intrin));
ast_function *func = intrin_value(intrin, &value, "epsilon", TYPE_FLOAT); ast_function *func = intrin_value(intrin, &value, "epsilon", TYPE_FLOAT);
vec_push(body->locals, eps); body->locals.push_back(eps);
/* eps = 1.0f; */ /* eps = 1.0f; */
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -1188,7 +1190,7 @@ static ast_expression *intrin_epsilon(intrin_t *intrin) {
) )
); );
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_loop_new( (ast_expression*)ast_loop_new(
intrin_ctx(intrin), intrin_ctx(intrin),
NULL, NULL,
@ -1223,7 +1225,7 @@ static ast_expression *intrin_epsilon(intrin_t *intrin) {
); );
/* return eps; */ /* return eps; */
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_return_new( (ast_expression*)ast_return_new(
intrin_ctx(intrin), intrin_ctx(intrin),
(ast_expression*)eps (ast_expression*)eps
@ -1248,9 +1250,9 @@ static ast_expression *intrin_nan(intrin_t *intrin) {
ast_function *func = intrin_value(intrin, &value, "nan", TYPE_FLOAT); ast_function *func = intrin_value(intrin, &value, "nan", TYPE_FLOAT);
ast_block *block = ast_block_new(intrin_ctx(intrin)); ast_block *block = ast_block_new(intrin_ctx(intrin));
vec_push(block->locals, x); block->locals.push_back(x);
vec_push(block->exprs, block->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -1259,7 +1261,7 @@ static ast_expression *intrin_nan(intrin_t *intrin) {
) )
); );
vec_push(block->exprs, block->exprs.push_back(
(ast_expression*)ast_return_new( (ast_expression*)ast_return_new(
intrin_ctx(intrin), intrin_ctx(intrin),
(ast_expression*)ast_binary_new( (ast_expression*)ast_binary_new(
@ -1292,12 +1294,12 @@ static ast_expression *intrin_inf(intrin_t *intrin) {
ast_block *block = ast_block_new(intrin_ctx(intrin)); ast_block *block = ast_block_new(intrin_ctx(intrin));
size_t i; size_t i;
vec_push(block->locals, x); block->locals.push_back(x);
vec_push(block->locals, y); block->locals.push_back(y);
/* to keep code size down */ /* to keep code size down */
for (i = 0; i <= 1; i++) { for (i = 0; i <= 1; i++) {
vec_push(block->exprs, block->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -1307,7 +1309,7 @@ static ast_expression *intrin_inf(intrin_t *intrin) {
); );
} }
vec_push(block->exprs, block->exprs.push_back(
(ast_expression*)ast_return_new( (ast_expression*)ast_return_new(
intrin_ctx(intrin), intrin_ctx(intrin),
(ast_expression*)ast_binary_new( (ast_expression*)ast_binary_new(
@ -1418,20 +1420,20 @@ static ast_expression *intrin_ln(intrin_t *intrin) {
ast_function *func = intrin_value(intrin, &value, "ln", TYPE_FLOAT); ast_function *func = intrin_value(intrin, &value, "ln", TYPE_FLOAT);
size_t i; size_t i;
vec_push(value->expression.params, power); value->expression.params.push_back(power);
vec_push(value->expression.params, base); value->expression.params.push_back(base);
vec_push(block->locals, whole); block->locals.push_back(whole);
vec_push(block->locals, nth); block->locals.push_back(nth);
vec_push(block->locals, sign); block->locals.push_back(sign);
vec_push(block->locals, eps); block->locals.push_back(eps);
vec_push(block->locals, A_i); block->locals.push_back(A_i);
vec_push(block->locals, B_i); block->locals.push_back(B_i);
vec_push(block->locals, A_iminus1); block->locals.push_back(A_iminus1);
vec_push(block->locals, B_iminus1); block->locals.push_back(B_iminus1);
/* sign = 1.0f; */ /* sign = 1.0f; */
vec_push(block->exprs, block->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -1441,7 +1443,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) {
); );
/* eps = __builtin_epsilon(); */ /* eps = __builtin_epsilon(); */
vec_push(block->exprs, block->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -1462,7 +1464,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) {
for (i = 0; i <= 1; i++) { for (i = 0; i <= 1; i++) {
int j; int j;
for (j = 1; j >= 0; j--) { for (j = 1; j >= 0; j--) {
vec_push(block->exprs, block->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -1485,7 +1487,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) {
* } * }
*/ */
for (i = 0; i <= 1; i++) { for (i = 0; i <= 1; i++) {
vec_push(((i) ? blt1 : plt1)->exprs, ((i) ? blt1 : plt1)->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -1498,7 +1500,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) {
) )
) )
); );
vec_push(plt1->exprs, plt1->exprs.push_back(
(ast_expression*)ast_binstore_new( (ast_expression*)ast_binstore_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -1519,7 +1521,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) {
* <blt1> * <blt1>
* } * }
*/ */
vec_push(plt1orblt1->exprs, plt1orblt1->exprs.push_back(
(ast_expression*)ast_ifthen_new( (ast_expression*)ast_ifthen_new(
intrin_ctx(intrin), intrin_ctx(intrin),
(ast_expression*)ast_binary_new( (ast_expression*)ast_binary_new(
@ -1550,7 +1552,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) {
); );
for (i = 0; i <= 1; i++) { for (i = 0; i <= 1; i++) {
vec_push(plt1orblt1->exprs, plt1orblt1->exprs.push_back(
(ast_expression*)ast_ifthen_new( (ast_expression*)ast_ifthen_new(
intrin_ctx(intrin), intrin_ctx(intrin),
(ast_expression*)ast_binary_new( (ast_expression*)ast_binary_new(
@ -1565,11 +1567,11 @@ static ast_expression *intrin_ln(intrin_t *intrin) {
); );
} }
vec_push(block->exprs, (ast_expression*)plt1orblt1); block->exprs.push_back((ast_expression*)plt1orblt1);
/* whole = power; */ /* whole = power; */
vec_push(forloop->exprs, forloop->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -1579,7 +1581,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) {
); );
/* nth = 0.0f; */ /* nth = 0.0f; */
vec_push(forloop->exprs, forloop->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -1589,7 +1591,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) {
); );
/* base2 = base; */ /* base2 = base; */
vec_push(whileloop->exprs, whileloop->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -1599,7 +1601,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) {
); );
/* n2 = 1.0f; */ /* n2 = 1.0f; */
vec_push(whileloop->exprs, whileloop->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -1609,7 +1611,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) {
); );
/* newbase2 = base2 * base2; */ /* newbase2 = base2 * base2; */
vec_push(whileloop->exprs, whileloop->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -1624,12 +1626,12 @@ static ast_expression *intrin_ln(intrin_t *intrin) {
); );
/* while loop locals */ /* while loop locals */
vec_push(whileloop->locals, base2); whileloop->locals.push_back(base2);
vec_push(whileloop->locals, n2); whileloop->locals.push_back(n2);
vec_push(whileloop->locals, newbase2); whileloop->locals.push_back(newbase2);
/* base2 = newbase2; */ /* base2 = newbase2; */
vec_push(nestwhile->exprs, nestwhile->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -1639,7 +1641,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) {
); );
/* n2 *= 2; */ /* n2 *= 2; */
vec_push(nestwhile->exprs, nestwhile->exprs.push_back(
(ast_expression*)ast_binstore_new( (ast_expression*)ast_binstore_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -1650,7 +1652,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) {
); );
/* newbase2 *= newbase2; */ /* newbase2 *= newbase2; */
vec_push(nestwhile->exprs, nestwhile->exprs.push_back(
(ast_expression*)ast_binstore_new( (ast_expression*)ast_binstore_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -1661,7 +1663,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) {
); );
/* while (whole >= newbase2) */ /* while (whole >= newbase2) */
vec_push(whileloop->exprs, whileloop->exprs.push_back(
(ast_expression*)ast_loop_new( (ast_expression*)ast_loop_new(
intrin_ctx(intrin), intrin_ctx(intrin),
NULL, NULL,
@ -1680,7 +1682,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) {
); );
/* whole /= base2; */ /* whole /= base2; */
vec_push(whileloop->exprs, whileloop->exprs.push_back(
(ast_expression*)ast_binstore_new( (ast_expression*)ast_binstore_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -1691,7 +1693,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) {
); );
/* nth += n2; */ /* nth += n2; */
vec_push(whileloop->exprs, whileloop->exprs.push_back(
(ast_expression*)ast_binstore_new( (ast_expression*)ast_binstore_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -1702,7 +1704,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) {
); );
/* while (whole >= base) */ /* while (whole >= base) */
vec_push(forloop->exprs, forloop->exprs.push_back(
(ast_expression*)ast_loop_new( (ast_expression*)ast_loop_new(
intrin_ctx(intrin), intrin_ctx(intrin),
NULL, NULL,
@ -1720,12 +1722,12 @@ static ast_expression *intrin_ln(intrin_t *intrin) {
) )
); );
vec_push(forloop->locals, b_iplus1); forloop->locals.push_back(b_iplus1);
vec_push(forloop->locals, A_iplus1); forloop->locals.push_back(A_iplus1);
vec_push(forloop->locals, B_iplus1); forloop->locals.push_back(B_iplus1);
/* b_iplus1 = nth; */ /* b_iplus1 = nth; */
vec_push(forloop->exprs, forloop->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -1739,7 +1741,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) {
* B_iplus1 = b_iplus1 * B_i + B_iminus1; * B_iplus1 = b_iplus1 * B_i + B_iminus1;
*/ */
for (i = 0; i <= 1; i++) { for (i = 0; i <= 1; i++) {
vec_push(forloop->exprs, forloop->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -1764,7 +1766,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) {
* B_iminus1 = B_i; * B_iminus1 = B_i;
*/ */
for (i = 0; i <= 1; i++) { for (i = 0; i <= 1; i++) {
vec_push(forloop->exprs, forloop->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -1779,7 +1781,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) {
* B_i = B_iplus1; * B_i = B_iplus1;
*/ */
for (i = 0; i <= 1; i++) { for (i = 0; i <= 1; i++) {
vec_push(forloop->exprs, forloop->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -1793,7 +1795,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) {
* if (whole <= 1.0f + eps) * if (whole <= 1.0f + eps)
* break; * break;
*/ */
vec_push(forloop->exprs, forloop->exprs.push_back(
(ast_expression*)ast_ifthen_new( (ast_expression*)ast_ifthen_new(
intrin_ctx(intrin), intrin_ctx(intrin),
(ast_expression*)ast_binary_new( (ast_expression*)ast_binary_new(
@ -1821,7 +1823,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) {
* base = whole; * base = whole;
*/ */
for (i = 0; i <= 1; i++) { for (i = 0; i <= 1; i++) {
vec_push(forloop->exprs, forloop->exprs.push_back(
(ast_expression*)ast_store_new( (ast_expression*)ast_store_new(
intrin_ctx(intrin), intrin_ctx(intrin),
INSTR_STORE_F, INSTR_STORE_F,
@ -1832,7 +1834,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) {
} }
/* add the for loop block */ /* add the for loop block */
vec_push(block->exprs, block->exprs.push_back(
(ast_expression*)ast_loop_new( (ast_expression*)ast_loop_new(
intrin_ctx(intrin), intrin_ctx(intrin),
NULL, NULL,
@ -1847,7 +1849,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) {
); );
/* return sign * A_i / B_il */ /* return sign * A_i / B_il */
vec_push(block->exprs, block->exprs.push_back(
(ast_expression*)ast_return_new( (ast_expression*)ast_return_new(
intrin_ctx(intrin), intrin_ctx(intrin),
(ast_expression*)ast_binary_new( (ast_expression*)ast_binary_new(
@ -1877,12 +1879,12 @@ static ast_expression *intrin_log_variant(intrin_t *intrin, const char *name, fl
ast_block *body = ast_block_new(intrin_ctx(intrin)); ast_block *body = ast_block_new(intrin_ctx(intrin));
ast_function *func = intrin_value(intrin, &value, name, TYPE_FLOAT); ast_function *func = intrin_value(intrin, &value, name, TYPE_FLOAT);
vec_push(value->expression.params, arg1); value->expression.params.push_back(arg1);
vec_push(callln->params, (ast_expression*)arg1); vec_push(callln->params, (ast_expression*)arg1);
vec_push(callln->params, (ast_expression*)fold_constgen_float(intrin->fold, base, false)); vec_push(callln->params, (ast_expression*)fold_constgen_float(intrin->fold, base, false));
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_return_new( (ast_expression*)ast_return_new(
intrin_ctx(intrin), intrin_ctx(intrin),
(ast_expression*)callln (ast_expression*)callln
@ -1921,8 +1923,8 @@ static ast_expression *intrin_shift_variant(intrin_t *intrin, const char *name,
ast_block *body = ast_block_new(intrin_ctx(intrin)); ast_block *body = ast_block_new(intrin_ctx(intrin));
ast_function *func = intrin_value(intrin, &value, name, TYPE_FLOAT); ast_function *func = intrin_value(intrin, &value, name, TYPE_FLOAT);
vec_push(value->expression.params, a); value->expression.params.push_back(a);
vec_push(value->expression.params, b); value->expression.params.push_back(b);
/* <callpow> = pow(2, b) */ /* <callpow> = pow(2, b) */
vec_push(callpow->params, (ast_expression*)intrin->fold->imm_float[3]); vec_push(callpow->params, (ast_expression*)intrin->fold->imm_float[3]);
@ -1940,7 +1942,7 @@ static ast_expression *intrin_shift_variant(intrin_t *intrin, const char *name,
); );
/* return <callfloor> */ /* return <callfloor> */
vec_push(body->exprs, body->exprs.push_back(
(ast_expression*)ast_return_new( (ast_expression*)ast_return_new(
intrin_ctx(intrin), intrin_ctx(intrin),
(ast_expression*)callfloor (ast_expression*)callfloor

View file

@ -80,11 +80,10 @@ static ast_expression* parser_find_field(parser_t *parser, const char *name)
static ast_expression* parser_find_label(parser_t *parser, const char *name) static ast_expression* parser_find_label(parser_t *parser, const char *name)
{ {
size_t i; for (auto &it : parser->labels)
for(i = 0; i < vec_size(parser->labels); i++) if (!strcmp(it->name, name))
if (!strcmp(parser->labels[i]->name, name)) return (ast_expression*)it;
return (ast_expression*)parser->labels[i]; return nullptr;
return NULL;
} }
ast_expression* parser_find_global(parser_t *parser, const char *name) ast_expression* parser_find_global(parser_t *parser, const char *name)
@ -97,14 +96,13 @@ ast_expression* parser_find_global(parser_t *parser, const char *name)
static ast_expression* parser_find_param(parser_t *parser, const char *name) static ast_expression* parser_find_param(parser_t *parser, const char *name)
{ {
size_t i;
ast_value *fun; ast_value *fun;
if (!parser->function) if (!parser->function)
return NULL; return NULL;
fun = parser->function->vtype; fun = parser->function->vtype;
for (i = 0; i < vec_size(fun->expression.params); ++i) { for (auto &it : fun->expression.params) {
if (!strcmp(fun->expression.params[i]->name, name)) if (!strcmp(it->name, name))
return (ast_expression*)(fun->expression.params[i]); return (ast_expression*)it;
} }
return NULL; return NULL;
} }
@ -341,7 +339,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
} }
} }
if (blocks[0] && !vec_size(blocks[0]->exprs) && op->id != opid1(',')) { if (blocks[0] && blocks[0]->exprs.empty() && op->id != opid1(',')) {
compile_error(ctx, "internal error: operator cannot be applied on empty blocks"); compile_error(ctx, "internal error: operator cannot be applied on empty blocks");
return false; return false;
} }
@ -1316,22 +1314,22 @@ static bool parser_close_call(parser_t *parser, shunt *sy)
ast_ctx(fun).line); ast_ctx(fun).line);
} }
if (vec_size(fun->params) != paramcount && if (fun->params.size() != paramcount &&
!((fun->flags & AST_FLAG_VARIADIC) && !((fun->flags & AST_FLAG_VARIADIC) &&
vec_size(fun->params) < paramcount)) fun->params.size() < paramcount))
{ {
const char *fewmany = (vec_size(fun->params) > paramcount) ? "few" : "many"; const char *fewmany = (fun->params.size() > paramcount) ? "few" : "many";
if (fval) if (fval)
return !parsewarning(parser, WARN_INVALID_PARAMETER_COUNT, return !parsewarning(parser, WARN_INVALID_PARAMETER_COUNT,
"too %s parameters for call to %s: expected %i, got %i\n" "too %s parameters for call to %s: expected %i, got %i\n"
" -> `%s` has been declared here: %s:%i", " -> `%s` has been declared here: %s:%i",
fewmany, fval->name, (int)vec_size(fun->params), (int)paramcount, fewmany, fval->name, (int)fun->params.size(), (int)paramcount,
fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line); fval->name, ast_ctx(fun).file, (int)ast_ctx(fun).line);
else else
return !parsewarning(parser, WARN_INVALID_PARAMETER_COUNT, return !parsewarning(parser, WARN_INVALID_PARAMETER_COUNT,
"too %s parameters for function call: expected %i, got %i\n" "too %s parameters for function call: expected %i, got %i\n"
" -> it has been declared here: %s:%i", " -> it has been declared here: %s:%i",
fewmany, (int)vec_size(fun->params), (int)paramcount, fewmany, (int)fun->params.size(), (int)paramcount,
ast_ctx(fun).file, (int)ast_ctx(fun).line); ast_ctx(fun).file, (int)ast_ctx(fun).line);
} }
} }
@ -1586,7 +1584,7 @@ static bool parse_sya_operand(parser_t *parser, shunt *sy, bool with_labels)
if (!with_labels) { if (!with_labels) {
ast_label *lbl = ast_label_new(parser_ctx(parser), parser_tokval(parser), true); ast_label *lbl = ast_label_new(parser_ctx(parser), parser_tokval(parser), true);
var = (ast_expression*)lbl; var = (ast_expression*)lbl;
vec_push(parser->labels, lbl); parser->labels.push_back(lbl);
} }
} }
if (!var && !strcmp(parser_tokval(parser), "__FUNC__")) if (!var && !strcmp(parser_tokval(parser), "__FUNC__"))
@ -2211,21 +2209,21 @@ static bool parse_while(parser_t *parser, ast_block *block, ast_expression **out
return false; return false;
} }
vec_push(parser->breaks, label); parser->breaks.push_back(label);
vec_push(parser->continues, label); parser->continues.push_back(label);
rv = parse_while_go(parser, block, out); rv = parse_while_go(parser, block, out);
if (label) if (label)
mem_d(label); mem_d(label);
if (vec_last(parser->breaks) != label || vec_last(parser->continues) != label) { if (parser->breaks.back() != label || parser->continues.back() != label) {
parseerror(parser, "internal error: label stack corrupted"); parseerror(parser, "internal error: label stack corrupted");
rv = false; rv = false;
ast_delete(*out); ast_delete(*out);
*out = NULL; *out = NULL;
} }
else { else {
vec_pop(parser->breaks); parser->breaks.pop_back();
vec_pop(parser->continues); parser->continues.pop_back();
} }
return rv; return rv;
} }
@ -2307,13 +2305,13 @@ static bool parse_dowhile(parser_t *parser, ast_block *block, ast_expression **o
} }
} }
vec_push(parser->breaks, label); parser->breaks.push_back(label);
vec_push(parser->continues, label); parser->continues.push_back(label);
rv = parse_dowhile_go(parser, block, out); rv = parse_dowhile_go(parser, block, out);
if (label) if (label)
mem_d(label); mem_d(label);
if (vec_last(parser->breaks) != label || vec_last(parser->continues) != label) { if (parser->breaks.back() != label || parser->continues.back() != label) {
parseerror(parser, "internal error: label stack corrupted"); parseerror(parser, "internal error: label stack corrupted");
rv = false; rv = false;
/* /*
@ -2325,8 +2323,8 @@ static bool parse_dowhile(parser_t *parser, ast_block *block, ast_expression **o
*out = NULL; *out = NULL;
} }
else { else {
vec_pop(parser->breaks); parser->breaks.pop_back();
vec_pop(parser->continues); parser->continues.pop_back();
} }
return rv; return rv;
} }
@ -2437,21 +2435,21 @@ static bool parse_for(parser_t *parser, ast_block *block, ast_expression **out)
return false; return false;
} }
vec_push(parser->breaks, label); parser->breaks.push_back(label);
vec_push(parser->continues, label); parser->continues.push_back(label);
rv = parse_for_go(parser, block, out); rv = parse_for_go(parser, block, out);
if (label) if (label)
mem_d(label); mem_d(label);
if (vec_last(parser->breaks) != label || vec_last(parser->continues) != label) { if (parser->breaks.back() != label || parser->continues.back() != label) {
parseerror(parser, "internal error: label stack corrupted"); parseerror(parser, "internal error: label stack corrupted");
rv = false; rv = false;
ast_delete(*out); ast_delete(*out);
*out = NULL; *out = NULL;
} }
else { else {
vec_pop(parser->breaks); parser->breaks.pop_back();
vec_pop(parser->continues); parser->continues.pop_back();
} }
return rv; return rv;
} }
@ -2672,10 +2670,10 @@ static bool parse_return(parser_t *parser, ast_block *block, ast_expression **ou
static bool parse_break_continue(parser_t *parser, ast_block *block, ast_expression **out, bool is_continue) static bool parse_break_continue(parser_t *parser, ast_block *block, ast_expression **out, bool is_continue)
{ {
size_t i; size_t i;
unsigned int levels = 0; unsigned int levels = 0;
lex_ctx_t ctx = parser_ctx(parser); lex_ctx_t ctx = parser_ctx(parser);
const char **loops = (is_continue ? parser->continues : parser->breaks); auto &loops = (is_continue ? parser->continues : parser->breaks);
(void)block; /* not touching */ (void)block; /* not touching */
if (!parser_next(parser)) { if (!parser_next(parser)) {
@ -2683,7 +2681,7 @@ static bool parse_break_continue(parser_t *parser, ast_block *block, ast_express
return false; return false;
} }
if (!vec_size(loops)) { if (loops.empty()) {
if (is_continue) if (is_continue)
parseerror(parser, "`continue` can only be used inside loops"); parseerror(parser, "`continue` can only be used inside loops");
else else
@ -2693,7 +2691,7 @@ static bool parse_break_continue(parser_t *parser, ast_block *block, ast_express
if (parser->tok == TOKEN_IDENT) { if (parser->tok == TOKEN_IDENT) {
if (!OPTS_FLAG(LOOP_LABELS)) if (!OPTS_FLAG(LOOP_LABELS))
parseerror(parser, "labeled loops not activated, try using -floop-labels"); parseerror(parser, "labeled loops not activated, try using -floop-labels");
i = vec_size(loops); i = loops.size();
while (i--) { while (i--) {
if (loops[i] && !strcmp(loops[i], parser_tokval(parser))) if (loops[i] && !strcmp(loops[i], parser_tokval(parser)))
break; break;
@ -2992,19 +2990,19 @@ static bool parse_switch(parser_t *parser, ast_block *block, ast_expression **ou
return false; return false;
} }
vec_push(parser->breaks, label); parser->breaks.push_back(label);
rv = parse_switch_go(parser, block, out); rv = parse_switch_go(parser, block, out);
if (label) if (label)
mem_d(label); mem_d(label);
if (vec_last(parser->breaks) != label) { if (parser->breaks.back() != label) {
parseerror(parser, "internal error: label stack corrupted"); parseerror(parser, "internal error: label stack corrupted");
rv = false; rv = false;
ast_delete(*out); ast_delete(*out);
*out = NULL; *out = NULL;
} }
else { else {
vec_pop(parser->breaks); parser->breaks.pop_back();
} }
return rv; return rv;
} }
@ -3263,7 +3261,7 @@ static bool parse_goto(parser_t *parser, ast_expression **out)
ast_goto_set_label(gt, (ast_label*)lbl); ast_goto_set_label(gt, (ast_label*)lbl);
} }
else else
vec_push(parser->gotos, gt); parser->gotos.push_back(gt);
if (!parser_next(parser) || parser->tok != ';') { if (!parser_next(parser) || parser->tok != ';') {
parseerror(parser, "semicolon expected after goto label"); parseerror(parser, "semicolon expected after goto label");
@ -3513,17 +3511,17 @@ static bool parse_statement(parser_t *parser, ast_block *block, ast_expression *
} }
else { else {
label = ast_label_new(parser_ctx(parser), parser_tokval(parser), false); label = ast_label_new(parser_ctx(parser), parser_tokval(parser), false);
vec_push(parser->labels, label); parser->labels.push_back(label);
} }
*out = (ast_expression*)label; *out = (ast_expression*)label;
if (!parser_next(parser)) { if (!parser_next(parser)) {
parseerror(parser, "parse error after label"); parseerror(parser, "parse error after label");
return false; return false;
} }
for (i = 0; i < vec_size(parser->gotos); ++i) { for (i = 0; i < parser->gotos.size(); ++i) {
if (!strcmp(parser->gotos[i]->name, label->name)) { if (!strcmp(parser->gotos[i]->name, label->name)) {
ast_goto_set_label(parser->gotos[i], label); ast_goto_set_label(parser->gotos[i], label);
vec_remove(parser->gotos, i, 1); parser->gotos.erase(parser->gotos.begin() + i);
--i; --i;
} }
} }
@ -3779,17 +3777,16 @@ static bool create_vector_members(ast_value *var, ast_member **me)
static bool parse_function_body(parser_t *parser, ast_value *var) static bool parse_function_body(parser_t *parser, ast_value *var)
{ {
ast_block *block = NULL; ast_block *block = NULL;
ast_function *func; ast_function *func;
ast_function *old; ast_function *old;
size_t parami;
ast_expression *framenum = NULL; ast_expression *framenum = NULL;
ast_expression *nextthink = NULL; ast_expression *nextthink = NULL;
/* None of the following have to be deleted */ /* None of the following have to be deleted */
ast_expression *fld_think = NULL, *fld_nextthink = NULL, *fld_frame = NULL; ast_expression *fld_think = NULL, *fld_nextthink = NULL, *fld_frame = NULL;
ast_expression *gbl_time = NULL, *gbl_self = NULL; ast_expression *gbl_time = NULL, *gbl_self = NULL;
bool has_frame_think; bool has_frame_think;
bool retval = true; bool retval = true;
@ -3801,7 +3798,7 @@ static bool parse_function_body(parser_t *parser, ast_value *var)
return false; return false;
} }
if (vec_size(parser->gotos) || vec_size(parser->labels)) { if (parser->gotos.size() || parser->labels.size()) {
parseerror(parser, "gotos/labels leaking"); parseerror(parser, "gotos/labels leaking");
return false; return false;
} }
@ -4044,19 +4041,18 @@ static bool parse_function_body(parser_t *parser, ast_value *var)
parser_enterblock(parser); parser_enterblock(parser);
for (parami = 0; parami < vec_size(var->expression.params); ++parami) { for (auto &it : var->expression.params) {
size_t e; size_t e;
ast_value *param = var->expression.params[parami];
ast_member *me[3]; ast_member *me[3];
if (param->expression.vtype != TYPE_VECTOR && if (it->expression.vtype != TYPE_VECTOR &&
(param->expression.vtype != TYPE_FIELD || (it->expression.vtype != TYPE_FIELD ||
param->expression.next->vtype != TYPE_VECTOR)) it->expression.next->vtype != TYPE_VECTOR))
{ {
continue; continue;
} }
if (!create_vector_members(param, me)) { if (!create_vector_members(it, me)) {
ast_block_delete(block); ast_block_delete(block);
goto enderrfn; goto enderrfn;
} }
@ -4092,7 +4088,7 @@ static bool parse_function_body(parser_t *parser, ast_value *var)
goto enderrfn; goto enderrfn;
} }
func->varargs = varargs; func->varargs = varargs;
func->fixedparams = (ast_value*)fold_constgen_float(parser->fold, vec_size(var->expression.params), false); func->fixedparams = (ast_value*)fold_constgen_float(parser->fold, var->expression.params.size(), false);
} }
parser->function = func; parser->function = func;
@ -4394,8 +4390,8 @@ static ast_value* parser_create_array_setter_proto(parser_t *parser, ast_value *
goto cleanup; goto cleanup;
} }
(void)!ast_value_set_name(value, "value"); /* not important */ (void)!ast_value_set_name(value, "value"); /* not important */
vec_push(fval->expression.params, index); fval->expression.params.push_back(index);
vec_push(fval->expression.params, value); fval->expression.params.push_back(value);
array->setter = fval; array->setter = fval;
return fval; return fval;
@ -4459,9 +4455,9 @@ static bool parser_create_array_field_setter(parser_t *parser, ast_value *array,
goto cleanup; goto cleanup;
} }
(void)!ast_value_set_name(value, "value"); /* not important */ (void)!ast_value_set_name(value, "value"); /* not important */
vec_push(fval->expression.params, entity); fval->expression.params.push_back(entity);
vec_push(fval->expression.params, index); fval->expression.params.push_back(index);
vec_push(fval->expression.params, value); fval->expression.params.push_back(value);
root = array_field_setter_node(parser, array, entity, index, value, 0, array->expression.count); root = array_field_setter_node(parser, array, entity, index, value, 0, array->expression.count);
if (!root) { if (!root) {
@ -4506,7 +4502,7 @@ static ast_value* parser_create_array_getter_proto(parser_t *parser, ast_value *
parseerror(parser, "failed to create locals for array accessor"); parseerror(parser, "failed to create locals for array accessor");
goto cleanup; goto cleanup;
} }
vec_push(fval->expression.params, index); fval->expression.params.push_back(index);
array->getter = fval; array->getter = fval;
return fval; return fval;
@ -4542,17 +4538,13 @@ static bool parser_create_array_getter(parser_t *parser, ast_value *array, const
static ast_value *parse_parameter_list(parser_t *parser, ast_value *var) static ast_value *parse_parameter_list(parser_t *parser, ast_value *var)
{ {
lex_ctx_t ctx; lex_ctx_t ctx = parser_ctx(parser);
size_t i; std::vector<ast_value *> params;
ast_value **params; ast_value *fval;
ast_value *param; bool first = true;
ast_value *fval; bool variadic = false;
bool first = true; ast_value *varparam = NULL;
bool variadic = false; char *argcounter = NULL;
ast_value *varparam = NULL;
char *argcounter = NULL;
ctx = parser_ctx(parser);
/* for the sake of less code we parse-in in this function */ /* for the sake of less code we parse-in in this function */
if (!parser_next(parser)) { if (!parser_next(parser)) {
@ -4561,8 +4553,6 @@ static ast_value *parse_parameter_list(parser_t *parser, ast_value *var)
return NULL; return NULL;
} }
params = NULL;
/* parse variables until we hit a closing paren */ /* parse variables until we hit a closing paren */
while (parser->tok != ')') { while (parser->tok != ')') {
bool is_varargs = false; bool is_varargs = false;
@ -4580,7 +4570,7 @@ static ast_value *parse_parameter_list(parser_t *parser, ast_value *var)
} }
first = false; first = false;
param = parse_typename(parser, NULL, NULL, &is_varargs); ast_value *param = parse_typename(parser, NULL, NULL, &is_varargs);
if (!param && !is_varargs) if (!param && !is_varargs)
goto on_error; goto on_error;
if (is_varargs) { if (is_varargs) {
@ -4598,7 +4588,7 @@ static ast_value *parse_parameter_list(parser_t *parser, ast_value *var)
} }
} }
} else { } else {
vec_push(params, param); params.push_back(param);
if (param->expression.vtype >= TYPE_VARIANT) { if (param->expression.vtype >= TYPE_VARIANT) {
char tname[1024]; /* typename is reserved in C++ */ char tname[1024]; /* typename is reserved in C++ */
ast_type_to_string((ast_expression*)param, tname, sizeof(tname)); ast_type_to_string((ast_expression*)param, tname, sizeof(tname));
@ -4608,8 +4598,8 @@ static ast_value *parse_parameter_list(parser_t *parser, ast_value *var)
/* type-restricted varargs */ /* type-restricted varargs */
if (parser->tok == TOKEN_DOTS) { if (parser->tok == TOKEN_DOTS) {
variadic = true; variadic = true;
varparam = vec_last(params); varparam = params.back();
vec_pop(params); params.pop_back();
if (!parser_next(parser) || (parser->tok != ')' && parser->tok != TOKEN_IDENT)) { if (!parser_next(parser) || (parser->tok != ')' && parser->tok != TOKEN_IDENT)) {
parseerror(parser, "`...` must be the last parameter of a variadic function declaration"); parseerror(parser, "`...` must be the last parameter of a variadic function declaration");
goto on_error; goto on_error;
@ -4630,11 +4620,11 @@ static ast_value *parse_parameter_list(parser_t *parser, ast_value *var)
} }
} }
if (vec_size(params) == 1 && params[0]->expression.vtype == TYPE_VOID) if (params.size() == 1 && params[0]->expression.vtype == TYPE_VOID)
vec_free(params); params.clear();
/* sanity check */ /* sanity check */
if (vec_size(params) > 8 && OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_QCC) if (params.size() > 8 && OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_QCC)
(void)!parsewarning(parser, WARN_EXTENSIONS, "more than 8 parameters are not supported by this standard"); (void)!parsewarning(parser, WARN_EXTENSIONS, "more than 8 parameters are not supported by this standard");
/* parse-out */ /* parse-out */
@ -4645,15 +4635,14 @@ static ast_value *parse_parameter_list(parser_t *parser, ast_value *var)
/* now turn 'var' into a function type */ /* now turn 'var' into a function type */
fval = ast_value_new(ctx, "<type()>", TYPE_FUNCTION); fval = ast_value_new(ctx, "<type()>", TYPE_FUNCTION);
fval->expression.next = (ast_expression*)var; fval->expression.next = (ast_expression*)var;
if (variadic) if (variadic)
fval->expression.flags |= AST_FLAG_VARIADIC; fval->expression.flags |= AST_FLAG_VARIADIC;
var = fval; var = fval;
var->expression.params = params; var->expression.params = params;
var->expression.varparam = (ast_expression*)varparam; var->expression.varparam = (ast_expression*)varparam;
var->argcounter = argcounter; var->argcounter = argcounter;
params = NULL;
return var; return var;
@ -4663,9 +4652,8 @@ on_error:
if (varparam) if (varparam)
ast_delete(varparam); ast_delete(varparam);
ast_delete(var); ast_delete(var);
for (i = 0; i < vec_size(params); ++i) for (auto &it : params)
ast_delete(params[i]); ast_delete(it);
vec_free(params);
return NULL; return NULL;
} }
@ -5255,7 +5243,7 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield
goto cleanup; goto cleanup;
} }
/* we need the new parameter-names */ /* we need the new parameter-names */
for (i = 0; i < vec_size(proto->expression.params); ++i) for (i = 0; i < proto->expression.params.size(); ++i)
ast_value_set_name(proto->expression.params[i], var->expression.params[i]->name); ast_value_set_name(proto->expression.params[i], var->expression.params[i]->name);
if (!parser_check_qualifiers(parser, var, proto)) { if (!parser_check_qualifiers(parser, var, proto)) {
retval = false; retval = false;
@ -5493,7 +5481,7 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield
} }
vec_free(defname); vec_free(defname);
} else { } else {
vec_push(localblock->locals, var); localblock->locals.push_back(var);
parser_addlocal(parser, var->name, (ast_expression*)var); parser_addlocal(parser, var->name, (ast_expression*)var);
if (isvector) { if (isvector) {
for (i = 0; i < 3; ++i) { for (i = 0; i < 3; ++i) {
@ -5704,10 +5692,8 @@ skipvar:
if (!parse_function_body(parser, var)) if (!parse_function_body(parser, var))
break; break;
ast_delete(basetype); ast_delete(basetype);
for (i = 0; i < vec_size(parser->gotos); ++i) for (auto &it : parser->gotos)
parseerror(parser, "undefined label: `%s`", parser->gotos[i]->name); parseerror(parser, "undefined label: `%s`", it->name);
vec_free(parser->gotos);
vec_free(parser->labels);
return true; return true;
} else { } else {
ast_expression *cexp; ast_expression *cexp;
@ -5727,7 +5713,7 @@ skipvar:
if (isvector) { if (isvector) {
for (i = 0; i < 3; ++i) { for (i = 0; i < 3; ++i) {
vec_pop(parser->_locals); vec_pop(parser->_locals);
vec_pop(localblock->collect); localblock->collect.pop_back();
} }
} }
/* do sanity checking, this function really needs refactoring */ /* do sanity checking, this function really needs refactoring */
@ -5735,10 +5721,10 @@ skipvar:
parseerror(parser, "internal error: unexpected change in local variable handling"); parseerror(parser, "internal error: unexpected change in local variable handling");
else else
vec_pop(parser->_locals); vec_pop(parser->_locals);
if (vec_last(localblock->locals) != var) if (localblock->locals.back() != var)
parseerror(parser, "internal error: unexpected change in local variable handling (2)"); parseerror(parser, "internal error: unexpected change in local variable handling (2)");
else else
vec_pop(localblock->locals); localblock->locals.pop_back();
/* push it to the to-be-generated globals */ /* push it to the to-be-generated globals */
vec_push(parser->globals, (ast_expression*)var); vec_push(parser->globals, (ast_expression*)var);
if (isvector) if (isvector)
@ -6000,6 +5986,9 @@ parser_t *parser_create()
memset(parser, 0, sizeof(*parser)); memset(parser, 0, sizeof(*parser));
// TODO: remove
new (parser) parser_t();
for (i = 0; i < operator_count; ++i) { for (i = 0; i < operator_count; ++i) {
if (operators[i].id == opid1('=')) { if (operators[i].id == opid1('=')) {
parser->assign_op = operators+i; parser->assign_op = operators+i;
@ -6141,11 +6130,6 @@ static void parser_remove_ast(parser_t *parser)
vec_free(parser->_block_ctx); vec_free(parser->_block_ctx);
vec_free(parser->labels);
vec_free(parser->gotos);
vec_free(parser->breaks);
vec_free(parser->continues);
ast_value_delete(parser->nil); ast_value_delete(parser->nil);
ast_value_delete(parser->const_vec[0]); ast_value_delete(parser->const_vec[0]);
@ -6194,7 +6178,7 @@ static bool parser_set_coverage_func(parser_t *parser, ir_builder *ir) {
cov = func->vtype; cov = func->vtype;
expr = (ast_expression*)cov; expr = (ast_expression*)cov;
if (expr->vtype != TYPE_FUNCTION || vec_size(expr->params) != 0) { if (expr->vtype != TYPE_FUNCTION || expr->params.size()) {
char ty[1024]; char ty[1024];
ast_type_to_string(expr, ty, sizeof(ty)); ast_type_to_string(expr, ty, sizeof(ty));
con_out("invalid type for coverage(): %s\n", ty); con_out("invalid type for coverage(): %s\n", ty);
@ -6270,8 +6254,8 @@ bool parser_finish(parser_t *parser, const char *output)
for (i = 0; i < vec_size(parser->functions); ++i) { for (i = 0; i < vec_size(parser->functions); ++i) {
ast_function *f = parser->functions[i]; ast_function *f = parser->functions[i];
if (f->varargs) { if (f->varargs) {
if (parser->max_param_count > vec_size(f->vtype->expression.params)) { if (parser->max_param_count > f->vtype->expression.params.size()) {
f->varargs->expression.count = parser->max_param_count - vec_size(f->vtype->expression.params); f->varargs->expression.count = parser->max_param_count - f->vtype->expression.params.size();
if (!parser_create_array_setter_impl(parser, f->varargs)) { if (!parser_create_array_setter_impl(parser, f->varargs)) {
con_out("failed to generate vararg setter for %s\n", f->name); con_out("failed to generate vararg setter for %s\n", f->name);
ir_builder_delete(ir); ir_builder_delete(ir);

View file

@ -58,10 +58,10 @@ struct parser_s {
/* All the labels the function defined... /* All the labels the function defined...
* Should they be in ast_function instead? * Should they be in ast_function instead?
*/ */
ast_label **labels; std::vector<ast_label*> labels;
ast_goto **gotos; std::vector<ast_goto*> gotos;
const char **breaks; std::vector<const char *> breaks;
const char **continues; std::vector<const char *> continues;
/* A list of hashtables for each scope */ /* A list of hashtables for each scope */
ht *variables; ht *variables;