printf("%c", ' ');
}
+static void print_char(char ch) {
+ switch (ch) {
+ case '\r': printf("__char('\\r')"); break;
+ case '\n': printf("__char('\\n')"); break;
+ case '\t': printf("__char('\\t')"); break;
+ case '\v': printf("__char('\\v')"); break;
+ default: printf("__char('%c')", ch); break;
+ }
+}
+
+static void print_string(const char* str) {
+ printf("__string(\"");
+ while('\0' != str[0])
+ {
+ switch (str[0]) {
+ case '\r': printf("\\r"); break;
+ case '\n': printf("\\n"); break;
+ case '\t': printf("\\t"); break;
+ case '\v': printf("\\v"); break;
+ default: printf("%c", str[0]); break;
+ }
+ str++;
+ }
+ printf("\")");
+}
+
+/*****************************************************************************/
+
static void emit_header(void) {
puts("#include <sclpl.h>\n");
}
if (p_tree->tag == ATOM) {
lex_tok_t* tok = p_tree->ptr.tok;
switch (tok->type) {
- case T_STRING: printf("__string(%s)", ((char*)tok->value)); break;
- case T_CHAR: printf("__char('%c')", ((char)(int)tok->value)); break;
+ case T_STRING: print_string(((char*)tok->value)); break;
+ case T_CHAR: print_char(((char)(int)tok->value)); break;
case T_INT: printf("__int(%ld)", *((long int*)tok->value)); break;
case T_FLOAT: printf("__float(%f)", *((double*)tok->value)); break;
case T_BOOL: printf("__bool(%s)", ((int)tok->value)?"true":"false"); break;
}
} else if (is_formtype(p_tree, "fn")) {
- printf("make(fn,&fn%d)", get_fn_id(fnlst, p_tree));
+ printf("__func(&fn%d)", get_fn_id(fnlst, p_tree));
} else {
- vec_t* vec = p_tree->ptr.vec;
- printf("apply(%s, ", (char*)get_val(vec_at(vec,0)));
+ vec_t* vec = p_tree->ptr.vec;
+ size_t nargs = vec_size(vec)-1;
+ /* Determine the calling convention based on number of args */
+ if (0 == nargs)
+ printf("__call0(%s", (char*)get_val(vec_at(vec,0)));
+ else if (nargs < 16)
+ printf("__calln(%s, %d, ", (char*)get_val(vec_at(vec,0)), nargs);
+ else
+ printf("__calln(%s, n, ", (char*)get_val(vec_at(vec,0)));
+ /* Print out the arguments */
for (size_t idx = 1; idx < vec_size(vec); idx++) {
emit_expression(fnlst, (tree_t*)vec_at(vec,idx), depth);
if (idx+1 < vec_size(vec))
} else if (lexer_oneof("()[]{};,'", text[0])) {
p_tok = lexer_punc(text);
} else if ('"' == text[0]) {
- p_tok = lex_tok_new(T_STRING, lexer_dup(text));
+ text[strlen(text)-1] = '\0';
+ p_tok = lex_tok_new(T_STRING, lexer_dup(&text[1]));
} else if (text[0] == '\\') {
p_tok = lexer_char(text);
} else if ((text[0] == '0') && lexer_oneof("bodh",text[1])) {
void pprint_token_value(FILE* file, lex_tok_t* token) {
void* value = token->value;
switch(token->type) {
- case T_STRING: fprintf(file, "%s", ((char*)value)); break;
+ case T_STRING: fprintf(file, "\"%s\"", ((char*)value)); break;
case T_CHAR: print_char(file, ((char)(int)value)); break;
case T_INT: fprintf(file, "%ld", *((long int*)value)); break;
case T_FLOAT: fprintf(file, "%f", *((double*)value)); break;
def x(a) 1;
def y(a,b) 2;
def z fn(a,b,c) 3;;
+
+w()
+x(1)
+y(1,2)
+z(1,2,3)
eos
ExpectedCode = <<-eos
_Value w;
_Value x;
_Value y;
+_Value z;
static _Value fn0();
static _Value fn1(_Value a);
static _Value fn2(_Value a, _Value b);
+static _Value fn3(_Value a, _Value b, _Value c);
static _Value fn0() {
return __int(0);
return __int(2);
}
+static _Value fn3(_Value a, _Value b, _Value c) {
+ return __int(3);
+}
+
void toplevel(void) {
+ extern void foo_toplevel(void);
+ foo_toplevel();
a = __int(123);
b = __int(123);
c = __int(-123);
w = __func(&fn0);
x = __func(&fn1);
y = __func(&fn2);
+ z = __func(&fn3);
+ (void)(__call0(w));
+ (void)(__calln(x, 1, __int(1)));
+ (void)(__calln(y, 2, __int(1), __int(2)));
+ (void)(__calln(z, 3, __int(1), __int(2), __int(3)));
}
int main(int argc, char** argv) {
describe "code generation" do
it "should generate some code" do
- pending "busted"
expect(ccode(InputSource)).to eq ExpectedCode
end
end