]> git.mdlowis.com Git - proto/sclpl.git/commitdiff
Tweaked function call, string, and character code generation
authorMichael D. Lowis <mike@mdlowis.com>
Tue, 21 Oct 2014 16:31:47 +0000 (12:31 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Tue, 21 Oct 2014 16:31:47 +0000 (12:31 -0400)
source/sclpl/codegen.c
source/sclpl/lexer.c
source/sclpl/main.c
source/sclpl/pprint.c
spec/codegen_spec.rb

index 8bc9324131553284798bba59828b2ae7a5b10cb2..a3ca7e80d2f51df3ee91e9e5711fb99bb77ea5a4 100644 (file)
@@ -84,6 +84,34 @@ static void print_indent(int depth) {
         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");
 }
@@ -113,8 +141,8 @@ static void emit_expression(vec_t* fnlst, tree_t* p_tree, int depth) {
     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;
@@ -137,10 +165,18 @@ static void emit_expression(vec_t* fnlst, tree_t* p_tree, int depth) {
         }
 
     } 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))
index d88fb25cc0829047715f76560f64f6946a1a4b64..c95c5f81dd2469ef1b76324fa1f32b60ef074c9d 100644 (file)
@@ -67,7 +67,8 @@ static lex_tok_t* lexer_make_token(char* text) {
     } 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])) {
index c01023629e58e1109bcbd29325c9739cbf2fb1e8..a4ae5ba790a98d9aaeb1ff43bf4a816d5e885066 100644 (file)
@@ -106,7 +106,8 @@ static int emit_csource(void) {
             ret = 1;
         }
     }
-    codegen_csource(stdout, p_vec);
+    if (0 == ret)
+        codegen_csource(stdout, p_vec);
     mem_release(p_vec);
     mem_release(p_parser);
     return ret;
@@ -146,8 +147,6 @@ static int emit_program(void) {
 
     * Formalize grammar for parser
     * Paren for function application must be on same line as variable in REPL
-    * skip line on error and terminate after full program parse
-    * skip line and print on error but do not terminate the REPL
 
 */
 int main(int argc, char **argv) {
index 166276dfc26ad03afb61e7fe3126354509974260..b6f9758b5d054831ae989273311bd8d5bc07c8c1 100644 (file)
@@ -59,7 +59,7 @@ void pprint_token_type(FILE* file, lex_tok_t* token) {
 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;
index d827bf0c7097d5bf39e1c9a3d9f866b17fecab3d..70cb9ae94aad5c684f924ecb178275f87a70e7a2 100644 (file)
@@ -29,6 +29,11 @@ def w() 0;
 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
@@ -59,10 +64,12 @@ _Value v;
 _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);
@@ -76,7 +83,13 @@ static _Value fn2(_Value a, _Value b) {
     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);
@@ -102,6 +115,11 @@ void toplevel(void) {
     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) {
@@ -114,7 +132,6 @@ eos
 
 describe "code generation" do
   it "should generate some code" do
-    pending "busted"
     expect(ccode(InputSource)).to eq ExpectedCode
   end
 end