]> git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
Handling some operands, added type_name array
authorWolfgang Bumiller <wolfgang.linux@bumiller.com>
Fri, 20 Jul 2012 19:19:30 +0000 (21:19 +0200)
committerWolfgang Bumiller <wolfgang.linux@bumiller.com>
Fri, 20 Jul 2012 19:19:30 +0000 (21:19 +0200)
gmqcc.h
ir.c
parser.c

diff --git a/gmqcc.h b/gmqcc.h
index 56c0ba4d0a09d13ea2cf1e364611ae041b36bb2a..59c8f47a0b298447662d0f6fc6b9b13a002a8992 100644 (file)
--- a/gmqcc.h
+++ b/gmqcc.h
@@ -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
diff --git a/ir.c b/ir.c
index d7756bbaea00e12e52287a5b246ef349027c4254..ef6791069096441e9d91f57f6ad53a0257222399 100644 (file)
--- a/ir.c
+++ b/ir.c
  * 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   */
index e03fc8fa741fe3d706e2d4c23c765912fe8ff2ba..2f267074ef9b7fb477274dcba75d7757947ea950 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -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;