aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cibic.l2
-rw-r--r--semantics.c54
-rw-r--r--ssa.c19
-rw-r--r--ssa.h4
4 files changed, 66 insertions, 13 deletions
diff --git a/cibic.l b/cibic.l
index 7ee0bf9..6dd82ac 100644
--- a/cibic.l
+++ b/cibic.l
@@ -90,7 +90,7 @@ char ([^\n'\\]|\\.|\\[0-7]+|\\[xX][0-9a-fA-F]+)
}
'{char}' {
- yylval.strval = strdup(yytext);
+ yylval.strval = strndup(yytext + 1, strlen(yytext) - 2);
return CHAR_CONST;
}
diff --git a/semantics.c b/semantics.c
index c1e2b29..4545303 100644
--- a/semantics.c
+++ b/semantics.c
@@ -493,7 +493,7 @@ CVar_t semantics_pdecl(CNode *p, CScope_t scope) {
CVar_t semantics_params(CNode *p, CScope_t scope) {
CHECK_TYPE(p, PARAMS);
static CVar dummy;
- CVar_t params = NULL;
+ CVar_t params = &dummy, tail = params;
CTable_t ct;
if (!(p = p->chd)) return NULL; /* no parameters */
ct = ctable_create(bkdr_hash, ctable_cvar_print);
@@ -504,16 +504,12 @@ CVar_t semantics_params(CNode *p, CScope_t scope) {
if (scope) /* params inside a function definition */
if (!ctable_insert(ct, var->name, var, 0))
ERROR((var->ast, "redefinition of parameter '%s'", var->name));
- var->next = params;
- params = var;
- /*
tail->next = var;
tail = var;
- */
}
ctable_destory(ct);
- /* tail->next = NULL; */
- return params;
+ tail->next = NULL;
+ return params->next;
}
ExpType semantics_exp(CNode *, CScope_t);
@@ -1196,7 +1192,49 @@ ExpType semantics_exp(CNode *p, CScope_t scope) {
res.type = basic_type_char;
res.lval = 0;
p->ext.is_const = 1;
- p->ext.const_val = p->rec.intval;
+ {
+ char *val = p->rec.strval;
+ int intval;
+ int len = strlen(val);
+ if (*val == '\\')
+ {
+ if (len == 2)
+ switch (val[1])
+ {
+ case 'a': intval = '\a'; break;
+ case 'b': intval = '\b'; break;
+ case 'f': intval = '\f'; break;
+ case 'n': intval = '\n'; break;
+ case 'r': intval = '\r'; break;
+ case 't': intval = '\t'; break;
+ case 'v': intval = '\v'; break;
+ case '\\': intval = '\\'; break;
+ case '\'': intval = '\''; break;
+ case '"': intval = '\"'; break;
+ case '\?': intval = '\?'; break;
+ case '0': intval = '\0'; break;
+ default:
+ ERROR((p, "unknown escape sequence"));
+ }
+ else
+ {
+ switch (val[1])
+ {
+ case '0':
+ sscanf(val + 2, "%o", &intval);
+ break;
+ case 'x':
+ sscanf(val + 2, "%x", &intval);
+ break;
+ default:
+ ERROR((p, "unknown escape sequence"));
+ }
+ }
+ }
+ else
+ intval = *val;
+ p->ext.const_val = intval;
+ }
break;
case STR:
{
diff --git a/ssa.c b/ssa.c
index 08bbb8a..6a7f450 100644
--- a/ssa.c
+++ b/ssa.c
@@ -94,6 +94,8 @@ void copr_print(COpr *opr) {
break;
case IMM: fprintf(stderr, "%d", opr->info.imm);
break;
+ case IMMS: fprintf(stderr, "\"%s\"", opr->info.str);
+ break;
}
}
@@ -253,7 +255,7 @@ COpr ssa_postfix(CNode *p, CBlock_t cur, CInst_t lval, CBlock_t succ) {
{
base->dest.kind = TMP;
base->dest.info.var = ctmp_create(rt);
- base->op = (rt->type == CSTRUCT || rt->type == CUNION) ? ADD : ARR;
+ base->op = ARR;
base->src1 = ssa_exp_(p->chd, cur, NULL, succ);
base->src2.kind = IMM;
base->src2.info.imm = p->ext.offset;
@@ -263,7 +265,7 @@ COpr ssa_postfix(CNode *p, CBlock_t cur, CInst_t lval, CBlock_t succ) {
{
base->dest.kind = TMP;
base->dest.info.var = ctmp_create(rt);
- base->op = (rt->type == CSTRUCT || rt->type == CUNION) ? ADD : ARR;
+ base->op = ARR;
base->src1 = ssa_exp_(p->chd, cur, NULL, succ);
base->src2.kind = IMM;
base->src2.info.imm = p->ext.offset;
@@ -272,6 +274,7 @@ COpr ssa_postfix(CNode *p, CBlock_t cur, CInst_t lval, CBlock_t succ) {
case POSTFIX_CALL:
{
CNode *arg = post->chd->chd;
+ CInst_t ps = NULL, t;
base->op = CALL;
base->src1 = ssa_exp_(p->chd, cur, lval, succ);
base->dest.kind = TMP;
@@ -281,7 +284,13 @@ COpr ssa_postfix(CNode *p, CBlock_t cur, CInst_t lval, CBlock_t succ) {
CInst_t pi = NEW(CInst);
pi->op = PUSH;
pi->src1 = ssa_exp_(arg, cur, lval, succ);
- cblock_append(cur, pi);
+ pi->next = ps;
+ ps = pi;
+ }
+ for (; ps; ps = t)
+ {
+ t = ps->next;
+ cblock_append(cur, ps);
}
}
break;
@@ -348,6 +357,10 @@ COpr ssa_exp_(CNode *p, CBlock_t cur, CInst_t lval, CBlock_t succ) {
lval->dest = res;
}
break;
+ case STR:
+ res.kind = IMMS;
+ res.info.str = p->rec.strval;
+ break;
default:
if (p->ext.is_const)
diff --git a/ssa.h b/ssa.h
index bc28414..cdd1894 100644
--- a/ssa.h
+++ b/ssa.h
@@ -6,11 +6,13 @@ typedef struct COpr {
enum {
VAR,
TMP,
- IMM
+ IMM,
+ IMMS
} kind;
union {
CVar_t var;
int imm;
+ char *str;
} info;
} COpr;