spl

a Simple Programming Language
Log | Files | Refs

cback.c (4716B)


      1 #include <stdio.h>
      2 
      3 #include "lexer.h"
      4 #include "parse.h"
      5 
      6 #define SAME(s1, s2) (strcmp(s1, s2) == 0)
      7 
      8 int vid = 0;
      9 
     10 void compilelexpr_C(lexpr *l, FILE *f); 
     11 int compilerexpr_C(rexpr *r, FILE *f); 
     12 
     13 int
     14 isbin(rexpr *r) {
     15 	switch (r->op) {
     16 	case ADD:
     17 	case SUB:
     18 	case MUL:
     19 	case DIV:
     20 		return 1;	
     21 	default: 
     22 		return 0;
     23 	}
     24 }
     25 
     26 char *
     27 toctype(char *type) {
     28 	static char ret[16];
     29 	if (SAME(type, "i8")) 
     30 		strcpy(ret, "int8_t");
     31 	else if (SAME(type, "i16")) 
     32 		strcpy(ret, "int16_t");
     33 	else if (SAME(type, "i32")) 
     34 		strcpy(ret, "int32_t");
     35 	else if (SAME(type, "i64")) 
     36 		strcpy(ret, "int64_t");
     37 	else if (SAME(type, "f32")) 
     38 		strcpy(ret, "float");
     39 	else if (SAME(type, "f64")) 
     40 		strcpy(ret, "double");
     41 	else if (SAME(type, "void")) 
     42 		strcpy(ret, "void");
     43 	else
     44 		return NULL;
     45 	return ret;
     46 }
     47 
     48 void 
     49 compiletype_C(type *t, FILE *f) {
     50 	switch (t->type) {
     51 	case BASIC:
     52 		fprintf(f, "%s", toctype(t->name));
     53 		break;
     54 	case PTR:
     55 		compiletype_C(t->nested, f);
     56 		fprintf(f, "*");
     57 		break;
     58 	case ARR:
     59 		fprintf(f, "array*");
     60 		break;
     61 	}
     62 }
     63 
     64 int
     65 compilefcall_C(rexpr *r, FILE *f) {
     66 	mctx *ctx = newctx();
     67 	int i, *ids = NULL;
     68 	for (i = 0; i < r->argc; i++) {
     69 		ids = realloczctx(ctx, ids, i + 1);
     70 		ids[i] = compilerexpr_C(&r->args[i], f);
     71 	}
     72 	if (!(r->type->type == BASIC && SAME(r->type->name, "void"))) {
     73 		compiletype_C(r->type, f);
     74 		fprintf(f, " v%d = %s(", vid++, r->fname);	
     75 	} else fprintf(f, "%s(", r->fname);	
     76 	if (!r->argc) fprintf(f, ");\n");
     77 	else 
     78 		for (int j = 0; j < i; j++) 
     79 			printf("v%d%s", ids[j], (j == i - 1) ? ");\n" : ", ");
     80 
     81 	freectx(ctx);
     82 	return vid - 1;
     83 }
     84 
     85 int
     86 compilerexpr_C(rexpr *r, FILE *f) {
     87 	int left, right;
     88 	switch (r->op) {
     89 	case INT:
     90 		compiletype_C(r->type, f);
     91 		fprintf(f, " v%d = %ld;\n", vid++, r->n);
     92 		return vid - 1;
     93 	case FLOAT:
     94 		compiletype_C(r->type, f);
     95 		fprintf(f, " v%d = %lf;\n", vid++, r->f);
     96 		return vid - 1;
     97 	case NAME:
     98 		compiletype_C(r->type, f);
     99 		fprintf(f, " v%d = %s;\n", vid++, r->name);
    100 		return vid - 1;
    101 	case DQUOTE:
    102 		compiletype_C(r->type, f);
    103 		fprintf(f, " v%d;\n", vid++);
    104 		return vid - 1;
    105 	case FUNCALL:
    106 		right = compilefcall_C(r, f);
    107 		compiletype_C(r->type, f);
    108 		fprintf(f, " v%d = v%d;\n", vid++, right, r->name);
    109 		return vid - 1;
    110 	case CAST:
    111 		right = compilerexpr_C(r->args, f);
    112 		compiletype_C(r->type, f);
    113 		fprintf(f, " v%d = (", vid++);
    114 		fprintf(f, "%s", toctype(r->fname));
    115 		fprintf(f, ")(v%d);\n", right);
    116 		break;
    117 	}
    118 
    119 	if (isbin(r)) {
    120 		left = compilerexpr_C(r->expr[0], f);
    121 		right = compilerexpr_C(r->expr[1], f);
    122 
    123 		compiletype_C(r->type, f);
    124 		fprintf(f, " v%d = v%d %c v%d;\n", vid++, left, r->op, right);
    125 	} else if (r->op == OBRACE) {
    126 		left = compilerexpr_C(r->expr[0], f);
    127 		compiletype_C(r->type, f);
    128 		fprintf(f, " v%d = v%d;\n", vid++, left);
    129 	}else if (r->op == NEGATE) {
    130 		left = compilerexpr_C(r->expr[0], f);
    131 		compiletype_C(r->type, f);
    132 		fprintf(f, " v%d = -v%d;\n", vid++, left);
    133 	} else if (r->op == ADDROF) {
    134 		left = compilerexpr_C(r->expr[0], f);
    135 		compiletype_C(r->type, f);
    136 		fprintf(f, " v%d = &v%d;\n", vid++, left);
    137 	} else if (r->op == DEREF) {
    138 		left = compilerexpr_C(r->expr[0], f);
    139 		compiletype_C(r->type, f);
    140 		fprintf(f, " v%d = *v%d;\n", vid++, left);
    141 	}
    142 	return vid - 1;
    143 }
    144 
    145 void
    146 compilefunc_C(lexpr *l, FILE *f) {
    147 	compiletype_C(l->rtype, f);
    148 	fprintf(f, " %s(", l->fname);
    149 	for (int i = 0; i < l->argc; i++) {
    150 		compiletype_C(l->args[i].type, f);
    151 		fprintf(f, " %s%s", l->args[i].name, (i == l->argc - 1) ? "" : ", ");
    152 	}
    153 	if (l->bodyc) {
    154 		fprintf(f, ") {\n");
    155 
    156 		for (int i = 0; i < l->bodyc; i++) {
    157 			compilelexpr_C(&l->body[i], f);
    158 		}
    159 
    160 		fprintf(f, "}\n");
    161 	}
    162 	else fprintf(f, ");\n");
    163 }
    164 
    165 void
    166 compileassign_C(lexpr *l, FILE *f) {
    167 	int id, sizeid;
    168 	if (l->rexpr) 
    169 		id = compilerexpr_C(l->rexpr, f);
    170 	if (l->type->type == ARR && l->type->size) 
    171 		sizeid = compilerexpr_C(l->type->size, f);
    172 
    173 	compiletype_C(l->type, f);
    174 	fprintf(f, " %s", l->name);
    175 
    176 	if (l->type->type == ARR) {
    177 		fprintf(f, " = newarray(");
    178 		if (l->type->size) fprintf(f, "v%d, sizeof(", sizeid);
    179 		else fprintf(f, "0, sizeof(");
    180 
    181 		compiletype_C(l->type->nested, f);
    182 		fprintf(f, "))");
    183 	}
    184 	if (l->rexpr) 
    185 		fprintf(f, " = v%d;\n", id);
    186 	else
    187 		fprintf(f, ";\n");
    188 }
    189 
    190 void
    191 compilereassign_C(lexpr *l, FILE *f) {
    192 	int id;
    193 	id = compilerexpr_C(l->rexpr, f);
    194 	fprintf(f, "%s = v%d;\n", l->name, id);
    195 }
    196 
    197 
    198 void
    199 compilelexpr_C(lexpr *l, FILE *f) {
    200 	switch (l->op) {
    201 	case LEXPR_FUNC:
    202 		compilefunc_C(l, f);
    203 		break;
    204 	case LEXPR_ASSIGN:
    205 		compileassign_C(l, f);
    206 		break;
    207 	case LEXPR_REASSIGN:
    208 		compilereassign_C(l, f);
    209 		break;
    210 	case RETURN:
    211 		if (l->ret)
    212 			fprintf(f, "return v%d;\n", compilerexpr_C(l->ret, f));
    213 		else
    214 			fprintf(f, "return;\n");
    215 		break;
    216 	case LEXPR_FCALL:
    217 		compilefcall_C(l->rexpr, f);
    218 		break;
    219 	}
    220 }