Handling some operands, added type_name array

This commit is contained in:
Wolfgang Bumiller 2012-07-20 21:19:30 +02:00
parent 439aef8c33
commit 071fd32040
3 changed files with 141 additions and 15 deletions

View file

@ -283,6 +283,8 @@ enum {
TYPE_COUNT
};
extern const char *type_name[TYPE_COUNT];
extern size_t type_sizeof[TYPE_COUNT];
extern uint16_t type_store_instr[TYPE_COUNT];
/* could use type_store_instr + INSTR_STOREP_F - INSTR_STORE_F

17
ir.c
View file

@ -29,6 +29,23 @@
* Type sizes used at multiple points in the IR codegen
*/
const char *type_name[TYPE_COUNT] = {
"void",
"string",
"float",
"vector",
"entity",
"field",
"function",
"pointer",
#if 0
"integer",
#endif
"quaternion",
"matrix",
"variant"
};
size_t type_sizeof[TYPE_COUNT] = {
1, /* TYPE_VOID */
1, /* TYPE_STRING */

137
parser.c
View file

@ -182,34 +182,49 @@ static ast_value *parser_parse_type(parser_t *parser, int basetype, bool *isfunc
typedef struct
{
size_t etype; /* 0 = expression, others are operators */
ast_expression* out;
ast_expression *out;
ast_value *value; /* need to know if we can assign */
lex_ctx ctx;
} sy_elem;
typedef struct
{
MEM_VECTOR_MAKE(sy_elem, out);
MEM_VECTOR_MAKE(sy_elem, ops);
} shynt;
MEM_VEC_FUNCTIONS(shynt, sy_elem, out)
MEM_VEC_FUNCTIONS(shynt, sy_elem, ops)
} shunt;
MEM_VEC_FUNCTIONS(shunt, sy_elem, out)
MEM_VEC_FUNCTIONS(shunt, sy_elem, ops)
static sy_elem syexp(ast_expression *v) {
static sy_elem syexp(lex_ctx ctx, ast_expression *v) {
sy_elem e;
e.etype = 0;
e.out = v;
e.out = v;
e.value = NULL;
e.ctx = ctx;
return e;
}
static sy_elem syval(lex_ctx ctx, ast_value *v) {
sy_elem e;
e.etype = 0;
e.out = (ast_expression*)v;
e.value = v;
e.ctx = ctx;
return e;
}
static sy_elem syval(ast_value *v) { return syexp((ast_expression*)v); }
static sy_elem syop(const oper_info *op) {
static sy_elem syop(lex_ctx ctx, const oper_info *op) {
sy_elem e;
e.etype = 1 + (op - operators);
e.out = NULL;
e.out = NULL;
e.value = NULL;
e.ctx = ctx;
return e;
}
static bool parser_sy_pop(parser_t *parser, shynt *sy)
static bool parser_sy_pop(parser_t *parser, shunt *sy)
{
const oper_info *op;
lex_ctx ctx;
ast_expression *out;
ast_expression *vals[3];
size_t i;
@ -219,6 +234,7 @@ static bool parser_sy_pop(parser_t *parser, shynt *sy)
}
op = &operators[sy->ops[sy->ops_count-1].etype - 1];
ctx = sy->ops[sy->ops_count-1].ctx;
if (sy->out_count < op->operands) {
parseerror(parser, "internal error: not enough operands");
@ -236,15 +252,106 @@ static bool parser_sy_pop(parser_t *parser, shynt *sy)
default:
parseerror(parser, "internal error: unhandled operand");
return false;
case opid1('+'):
if (vals[0]->expression.vtype != vals[1]->expression.vtype) {
parseerror(parser, "Cannot add type %s and %s",
type_name[vals[0]->expression.vtype],
type_name[vals[1]->expression.vtype]);
break;
}
switch (vals[0]->expression.vtype) {
case TYPE_FLOAT:
out = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_F, vals[0], vals[1]);
break;
case TYPE_VECTOR:
out = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_V, vals[0], vals[1]);
break;
default:
parseerror(parser, "Cannot add type %s and %s",
type_name[vals[0]->expression.vtype],
type_name[vals[1]->expression.vtype]);
return false;
};
break;
case opid1('-'):
if (vals[0]->expression.vtype != vals[1]->expression.vtype) {
parseerror(parser, "Cannot subtract type %s from %s",
type_name[vals[1]->expression.vtype],
type_name[vals[0]->expression.vtype]);
break;
}
switch (vals[0]->expression.vtype) {
case TYPE_FLOAT:
out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_F, vals[0], vals[1]);
break;
case TYPE_VECTOR:
out = (ast_expression*)ast_binary_new(ctx, INSTR_SUB_V, vals[0], vals[1]);
break;
default:
parseerror(parser, "Cannot add type %s from %s",
type_name[vals[1]->expression.vtype],
type_name[vals[0]->expression.vtype]);
return false;
};
break;
case opid1('*'):
if (vals[0]->expression.vtype != vals[1]->expression.vtype &&
vals[0]->expression.vtype != TYPE_VECTOR &&
vals[0]->expression.vtype != TYPE_FLOAT &&
vals[1]->expression.vtype != TYPE_VECTOR &&
vals[1]->expression.vtype != TYPE_FLOAT)
{
parseerror(parser, "Cannot multiply type %s from %s",
type_name[vals[1]->expression.vtype],
type_name[vals[0]->expression.vtype]);
break;
}
switch (vals[0]->expression.vtype) {
case TYPE_FLOAT:
if (vals[1]->expression.vtype == TYPE_VECTOR)
out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_FV, vals[0], vals[1]);
else
out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, vals[0], vals[1]);
break;
case TYPE_VECTOR:
if (vals[1]->expression.vtype == TYPE_FLOAT)
out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_VF, vals[0], vals[1]);
else
out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_V, vals[0], vals[1]);
break;
default:
parseerror(parser, "Cannot add type %s from %s",
type_name[vals[1]->expression.vtype],
type_name[vals[0]->expression.vtype]);
return false;
};
break;
case opid1('/'):
if (vals[0]->expression.vtype != vals[1]->expression.vtype ||
vals[0]->expression.vtype != TYPE_FLOAT)
{
parseerror(parser, "Cannot divide types %s and %s",
type_name[vals[0]->expression.vtype],
type_name[vals[1]->expression.vtype]);
break;
}
out = (ast_expression*)ast_binary_new(ctx, INSTR_DIV_F, vals[0], vals[1]);
break;
case opid1('='):
break;
}
sy->ops[sy->ops_count++] = syexp(ctx, out);
return true;
}
static ast_expression* parser_expression(parser_t *parser)
{
ast_expression *expr = NULL;
shynt sy;
shunt sy;
bool wantop = false;
MEM_VECTOR_INIT(&sy, out);
@ -262,7 +369,7 @@ static ast_expression* parser_expression(parser_t *parser)
parseerror(parser, "unexpected ident: %s", parser_tokval(parser));
goto onerr;
}
if (!shynt_out_add(&sy, syval(var))) {
if (!shunt_out_add(&sy, syval(parser_ctx(parser), var))) {
parseerror(parser, "out of memory");
goto onerr;
}
@ -270,7 +377,7 @@ static ast_expression* parser_expression(parser_t *parser)
ast_value *val = parser_const_float(parser, (parser_token(parser)->constval.f));
if (!val)
return false;
if (!shynt_out_add(&sy, syval(val))) {
if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
parseerror(parser, "out of memory");
goto onerr;
}
@ -278,7 +385,7 @@ static ast_expression* parser_expression(parser_t *parser)
ast_value *val = parser_const_float(parser, (double)(parser_token(parser)->constval.i));
if (!val)
return false;
if (!shynt_out_add(&sy, syval(val))) {
if (!shunt_out_add(&sy, syexp(parser_ctx(parser), (ast_expression*)val))) {
parseerror(parser, "out of memory");
goto onerr;
}
@ -329,7 +436,7 @@ static ast_expression* parser_expression(parser_t *parser)
olast = sy.ops_count ? (&operators[sy.ops[sy.ops_count-1].etype-1]) : NULL;
}
if (!shynt_ops_add(&sy, syop(op)))
if (!shunt_ops_add(&sy, syop(parser_ctx(parser), op)))
goto onerr;
}
wantop = false;