2 Incheckningar dc825ca537 ... 592ccd454f

Upphovsman SHA1 Meddelande Datum
  Matt Coles 592ccd454f go nuts 8 år sedan
  Matt Coles faee9f9ac1 never ending quest for portable bash scripts 8 år sedan
15 ändrade filer med 278 tillägg och 150 borttagningar
  1. 140 80
      cw/main.c
  2. 9 14
      cw/simple.c
  3. 3 0
      cw/tests/cond_loop.c
  4. 17 0
      cw/tests/cplus.c
  5. 1 4
      cw/tests/func_args.c
  6. 2 0
      cw/tests/func_call.c
  7. 4 0
      cw/tests/modulo.c
  8. 37 0
      cw/tests/new_test.sh
  9. 17 0
      cw/tests/recursion.c
  10. 1 0
      cw/tests/return_only.c
  11. 4 0
      cw/tests/sub.c
  12. 25 52
      cw/tests/test.sh
  13. 16 0
      cw/tests/twice.c
  14. 1 0
      cw/tests/var_maths.c
  15. 1 0
      cw/types.h

+ 140 - 80
cw/main.c

10
 TOKEN* lookup_token(char *s);
10
 TOKEN* lookup_token(char *s);
11
 int asprintf(char **strp, const char *fmt, ...);
11
 int asprintf(char **strp, const char *fmt, ...);
12
 
12
 
13
+int debug = 0;
14
+
13
 /*
15
 /*
14
  * Existing problems/todo:
16
  * Existing problems/todo:
15
  * return from control block, need a "return address" to jump to -- call levels
17
  * return from control block, need a "return address" to jump to -- call levels
102
 }
104
 }
103
 
105
 
104
 // forward declare because it is used in add_var_to_env
106
 // forward declare because it is used in add_var_to_env
105
-int recursive_interpret(NODE*, ENV*);
107
+BIND* recursive_interpret(NODE*, ENV*);
106
 
108
 
107
 void print_tree(NODE *tree) {
109
 void print_tree(NODE *tree) {
108
     print_tree0(tree, 0);
110
     print_tree0(tree, 0);
121
   return a;
123
   return a;
122
 }
124
 }
123
 
125
 
124
-void add_args_to_env(NODE *tree, ENV *env_ptr) {
125
-  if (tree->type == '~') {
126
-    BIND* arg;
127
-    TOKEN *tok, *name;
128
-    // we found an argument
129
-    name = (TOKEN*)tree->right->left;
130
-    tok = new_token(INT);
131
-    tok->value = 0;
132
-    asprintf(&tok->lexeme, "%d", tok->value);
133
-    arg = create_binding(name, (NODE*) tok, NULL);
134
-    if (env_ptr->bindings == NULL) {
135
-      env_ptr->bindings = create_list(arg, NULL);
136
-    } else {
137
-      append_list(env_ptr->bindings, arg);
138
-    }
139
-  } else {
140
-    add_args_to_env(tree->left, env_ptr);
141
-    add_args_to_env(tree->right, env_ptr);
142
-  }
143
-}
144
-
145
 void populate_arg_list(NODE *tree, TOKEN** arr, int arr_len) {
126
 void populate_arg_list(NODE *tree, TOKEN** arr, int arr_len) {
146
   if (tree->type == '~') {
127
   if (tree->type == '~') {
147
     for (int i = 0; i < arr_len; i++) {
128
     for (int i = 0; i < arr_len; i++) {
169
   NODE* func_name = tree->left->right->left->left;
150
   NODE* func_name = tree->left->right->left->left;
170
   TOKEN* name_token = (TOKEN*) func_name;
151
   TOKEN* name_token = (TOKEN*) func_name;
171
   if ((existing = find_name_in_env(name_token, env_ptr)) == NULL) {
152
   if ((existing = find_name_in_env(name_token, env_ptr)) == NULL) {
172
-    ENV* new_func_env = create_new_function_env(env_ptr);
173
-    if (tree->left->right->right != NULL) {
174
-      add_args_to_env(tree->left->right->right, new_func_env);
175
-    }
176
     if (env_ptr->bindings == NULL) {
153
     if (env_ptr->bindings == NULL) {
177
-      env_ptr->bindings = create_list(create_binding(name_token, tree, new_func_env), NULL);
154
+      env_ptr->bindings = create_list(create_binding(name_token, tree, env_ptr), NULL);
178
     } else {
155
     } else {
179
-      append_list(env_ptr->bindings, create_binding(name_token, tree, new_func_env));
156
+      append_list(env_ptr->bindings, create_binding(name_token, tree, env_ptr));
180
     }
157
     }
181
   } else {
158
   } else {
182
     printf("Error: redefinition of function with name %s\n", name_token->lexeme);
159
     printf("Error: redefinition of function with name %s\n", name_token->lexeme);
183
   }
160
   }
184
 }
161
 }
185
 
162
 
186
-void populate_val_list(NODE* tree, TOKEN** arr, int num_args) {
187
-  if (tree->type == LEAF) {
163
+void populate_val_list(NODE* tree, NODE** arr, int num_args, ENV* env_ptr) {
164
+  if (tree->type == ',') {
165
+    populate_val_list(tree->left, arr, num_args, env_ptr);
166
+    populate_val_list(tree->right, arr, num_args, env_ptr);
167
+  } else {
188
     for (int i = 0; i < num_args; i++) {
168
     for (int i = 0; i < num_args; i++) {
189
       if (arr[i] == NULL) {
169
       if (arr[i] == NULL) {
190
-        TOKEN* tok = (TOKEN*) tree->left;
191
-        arr[i] = tok;
170
+        arr[i] = tree;
192
         break;
171
         break;
193
       }
172
       }
194
     }
173
     }
195
-  } else {
196
-    populate_val_list(tree->left, arr, num_args);
197
-    populate_val_list(tree->right, arr, num_args);
198
   }
174
   }
199
 }
175
 }
200
 
176
 
201
-TOKEN** get_val_list(NODE *tree) {
177
+NODE** get_val_list(NODE *tree, ENV* env_ptr) {
202
   int num_args = count_args(tree);
178
   int num_args = count_args(tree);
203
-  TOKEN** arr = (TOKEN**) malloc(sizeof(TOKEN*) * num_args);
204
-  populate_val_list(tree, arr, num_args);
179
+  NODE** arr = (NODE**) malloc(sizeof(NODE*) * num_args);
180
+  populate_val_list(tree, arr, num_args, env_ptr);
205
   return arr;
181
   return arr;
206
 }
182
 }
207
 
183
 
208
-void bind_arg(TOKEN* val, TOKEN* arg_name, ENV *env_ptr) {
209
-  BIND* existing = find_name_in_list(arg_name, env_ptr->bindings);
210
-  if (existing == NULL) {
211
-    printf("Attempted to bind arg that doesn't exist, the compiler is broken\n");
212
-    exit(1);
184
+void bind_arg(NODE* val, TOKEN* arg_name, ENV *env_ptr, ENV* src_env) {
185
+  BIND* result = recursive_interpret(val, src_env);
186
+  if(debug)printf("Binding argument: %s\n", arg_name->lexeme);
187
+  if (env_ptr->bindings == NULL) {
188
+    env_ptr->bindings = create_list(create_binding(arg_name, result->tree, result->env), NULL);
189
+  } else {
190
+    BIND* existing = find_name_in_list(arg_name, env_ptr->bindings);
191
+    if (existing) {
192
+      existing->tree = result->tree;
193
+    } else {
194
+      append_list(env_ptr->bindings, create_binding(arg_name, result->tree, result->env));
195
+    }
213
   }
196
   }
214
-  existing->tree = (NODE*) val;
215
 }
197
 }
216
 
198
 
217
 void add_var_to_env(NODE *tree, ENV *env_ptr) {
199
 void add_var_to_env(NODE *tree, ENV *env_ptr) {
218
   BIND* existing;
200
   BIND* existing;
219
   NODE* var_name = tree->left->left;
201
   NODE* var_name = tree->left->left;
220
   TOKEN* name_token = (TOKEN*) var_name;
202
   TOKEN* name_token = (TOKEN*) var_name;
221
-  TOKEN* tok = new_token(CONSTANT);
222
-  tok->value = recursive_interpret(tree->right, env_ptr);
223
-  asprintf(&tok->lexeme, "%d", tok->value);
203
+  if (debug) printf("assigning %s:\n", name_token->lexeme);
204
+  BIND* node = recursive_interpret(tree->right, env_ptr);
224
   if ((existing = find_name_in_env(name_token, env_ptr)) == NULL) {
205
   if ((existing = find_name_in_env(name_token, env_ptr)) == NULL) {
225
     if (env_ptr->bindings == NULL) {
206
     if (env_ptr->bindings == NULL) {
226
-      env_ptr->bindings = create_list(create_binding(name_token, (NODE*) tok, NULL), NULL);
207
+      env_ptr->bindings = create_list(create_binding(name_token, node->tree, node->env), NULL);
227
     } else {
208
     } else {
228
-      append_list(env_ptr->bindings, create_binding(name_token, (NODE*) tok, NULL));
209
+      append_list(env_ptr->bindings, create_binding(name_token, node->tree, node->env));
229
     }
210
     }
230
   } else {
211
   } else {
231
-    existing->tree = (NODE *) tok;
212
+    existing->tree = node->tree;
232
   } 
213
   } 
233
 }
214
 }
234
 
215
 
235
-int recursive_interpret(NODE *tree, ENV *env_ptr) {
236
-  if (tree==NULL) return 0;
216
+TOKEN* get_int_token(int value) {
217
+  TOKEN* res;
218
+  char buffer[20];
219
+  snprintf(buffer, 20, "%d", value);
220
+  res = lookup_token(buffer);
221
+  if (res->type != CONSTANT) res->type = CONSTANT;
222
+  if (res->value != value) res->value = value;
223
+  return res;
224
+}
225
+
226
+BIND* anon_binding(NODE *tree) {
227
+  return create_binding(NULL, tree, NULL);
228
+}
229
+
230
+BIND* ret_val;
231
+int returning;
232
+
233
+BIND* recursive_interpret(NODE *tree, ENV *env_ptr) {
234
+  if (returning == 1) return NULL;
235
+  if (tree==NULL) return NULL;
237
   if (tree->type==LEAF) {
236
   if (tree->type==LEAF) {
238
     if (tree->left->type == CONSTANT) {
237
     if (tree->left->type == CONSTANT) {
239
-      return ((TOKEN *) tree->left)->value;
238
+      return anon_binding(tree->left);
240
     } else if (tree->left->type == STRING_LITERAL) {
239
     } else if (tree->left->type == STRING_LITERAL) {
241
       printf("Not implemented\n");
240
       printf("Not implemented\n");
242
       exit(1);
241
       exit(1);
243
     } else if (tree->left->type == INT || tree->left->type == FUNCTION) {
242
     } else if (tree->left->type == INT || tree->left->type == FUNCTION) {
244
       // do nothing we dont care about types for now
243
       // do nothing we dont care about types for now
245
-      return 0;
244
+      return NULL;
246
     } else {
245
     } else {
247
       // an identifier
246
       // an identifier
248
       TOKEN* tok = (TOKEN *) tree->left;
247
       TOKEN* tok = (TOKEN *) tree->left;
249
       BIND* var_bind = find_name_in_env(tok, env_ptr);
248
       BIND* var_bind = find_name_in_env(tok, env_ptr);
249
+      if (debug) {
250
+        printf("looking up %s\n", tok->lexeme);
251
+      }
250
       if (var_bind == NULL) {
252
       if (var_bind == NULL) {
251
         printf("Could not find variable %s\n", tok->lexeme);
253
         printf("Could not find variable %s\n", tok->lexeme);
252
         exit(1);
254
         exit(1);
253
       }
255
       }
256
+      if(debug)printf("I got: ");
254
       if (var_bind->tree->type == CONSTANT) {
257
       if (var_bind->tree->type == CONSTANT) {
255
-        TOKEN* var_tok = (TOKEN *) var_bind->tree;
256
-        return var_tok->value;
258
+        if(debug){
259
+          printf("CONSTANT\n");
260
+          print_leaf(var_bind->tree, 0);
261
+        }
257
       } else {
262
       } else {
258
-        printf("Maybe got a function?\n");
259
-        return 0;
263
+        if(debug)print_tree(var_bind->tree);
260
       }
264
       }
265
+      return var_bind;
266
+      /* if (var_bind->tree->type == CONSTANT) { */
267
+      /*   return var_bind->tree; */
268
+      /* } else { */
269
+      /*   print_tree(var_bind->tree); */
270
+      /*   printf("I GOT A %d from %s\n", var_bind->tree->type, var_bind->name->lexeme); */
271
+      /*   printf("Maybe got a function?\n"); */
272
+      /*   return NULL; */
273
+      /* } */
261
     }
274
     }
262
   }
275
   }
263
   if (tree->type=='D') {
276
   if (tree->type=='D') {
264
     // this is a function definition
277
     // this is a function definition
265
     add_function_to_env(tree, env_ptr);
278
     add_function_to_env(tree, env_ptr);
266
-    return 0;
279
+    return NULL;
267
   }
280
   }
268
   if (tree->type=='=') {
281
   if (tree->type=='=') {
269
     // this is a variable definition
282
     // this is a variable definition
270
     add_var_to_env(tree, env_ptr);
283
     add_var_to_env(tree, env_ptr);
271
-    return 0;
284
+    return NULL;
272
   }
285
   }
273
   if (tree->type==APPLY) {
286
   if (tree->type==APPLY) {
274
     TOKEN* func_name = ((TOKEN*) tree->left->left);
287
     TOKEN* func_name = ((TOKEN*) tree->left->left);
277
       printf("Could not find binding for function with name %s\n", func_name->lexeme);
290
       printf("Could not find binding for function with name %s\n", func_name->lexeme);
278
       exit(1);
291
       exit(1);
279
     }
292
     }
293
+    ENV* new_func_env = create_new_function_env(func->env);
294
+    if (debug) printf("Calling function %s\n", func_name->lexeme);
280
     if (tree->right != NULL) {
295
     if (tree->right != NULL) {
281
-      TOKEN **arg_list, **val_list;
296
+      TOKEN **arg_list;
297
+      NODE **val_list;
282
       int exp_args, num_args;
298
       int exp_args, num_args;
283
       exp_args = count_args(func->tree->left->right->right);
299
       exp_args = count_args(func->tree->left->right->right);
284
       num_args = count_args(tree->right);
300
       num_args = count_args(tree->right);
285
       arg_list = get_argument_list(func->tree);
301
       arg_list = get_argument_list(func->tree);
286
-      val_list = get_val_list(tree->right);
302
+      val_list = get_val_list(tree->right, env_ptr);
287
       if (exp_args == num_args) {
303
       if (exp_args == num_args) {
288
         for (int i = 0; i < num_args; i++) {
304
         for (int i = 0; i < num_args; i++) {
289
-          bind_arg(val_list[i], arg_list[i], func->env);
305
+          bind_arg(val_list[i], arg_list[i], new_func_env, env_ptr);
290
         }
306
         }
291
       } else {
307
       } else {
292
         printf("Incorrect arguments passed to function %s, expected %d got %d\n", func_name->lexeme, exp_args, num_args);
308
         printf("Incorrect arguments passed to function %s, expected %d got %d\n", func_name->lexeme, exp_args, num_args);
293
         exit(1);
309
         exit(1);
294
       }
310
       }
295
     }
311
     }
296
-    return recursive_interpret(func->tree->right, func->env);
312
+    recursive_interpret(func->tree->right, new_func_env);
313
+    if (returning == 1) {
314
+      returning = 0;
315
+      return ret_val;
316
+    } else {
317
+      printf("HELP called a function with no return!!\n");
318
+    }
297
   }
319
   }
298
   if (tree->type == IF) {
320
   if (tree->type == IF) {
299
-    if (recursive_interpret(tree->left, env_ptr) == 1) {
321
+    if (((TOKEN*)recursive_interpret(tree->left, env_ptr)->tree)->value == 1) {
300
       ENV* scope_env = create_new_function_env(env_ptr);
322
       ENV* scope_env = create_new_function_env(env_ptr);
301
       if (tree->right->type == ELSE) {
323
       if (tree->right->type == ELSE) {
302
         return recursive_interpret(tree->right->left, scope_env);
324
         return recursive_interpret(tree->right->left, scope_env);
312
     }
334
     }
313
   }
335
   }
314
   if (tree->type == LE_OP) {
336
   if (tree->type == LE_OP) {
315
-    return (int)recursive_interpret(tree->left, env_ptr) <= recursive_interpret(tree->right, env_ptr);
337
+    TOKEN* lhs = (TOKEN*) recursive_interpret(tree->left, env_ptr)->tree;
338
+    TOKEN* rhs = (TOKEN*) recursive_interpret(tree->right, env_ptr)->tree;
339
+    int result = lhs->value <= rhs->value;
340
+    return anon_binding((NODE*) get_int_token(result));
316
   }
341
   }
317
   if (tree->type == GE_OP) {
342
   if (tree->type == GE_OP) {
318
-    return (int)recursive_interpret(tree->left, env_ptr) >= recursive_interpret(tree->right, env_ptr);
343
+    TOKEN* lhs = (TOKEN*) recursive_interpret(tree->left, env_ptr)->tree;
344
+    TOKEN* rhs = (TOKEN*) recursive_interpret(tree->right, env_ptr)->tree;
345
+    int result = lhs->value >= rhs->value;
346
+    return anon_binding((NODE*) get_int_token(result));
319
   }
347
   }
320
   if (tree->type == EQ_OP) {
348
   if (tree->type == EQ_OP) {
321
-    return (int)recursive_interpret(tree->left, env_ptr) == recursive_interpret(tree->right, env_ptr);
349
+    TOKEN* lhs = (TOKEN*) recursive_interpret(tree->left, env_ptr)->tree;
350
+    TOKEN* rhs = (TOKEN*) recursive_interpret(tree->right, env_ptr)->tree;
351
+    if (debug) printf("Comparing %d == %d\n", lhs->value, rhs->value);
352
+    int result = lhs->value == rhs->value;
353
+    return anon_binding((NODE*) get_int_token(result));
322
   }
354
   }
323
   if (tree->type == NE_OP) {
355
   if (tree->type == NE_OP) {
324
-    return (int)recursive_interpret(tree->left, env_ptr) != recursive_interpret(tree->right, env_ptr);
356
+    TOKEN* lhs = (TOKEN*) recursive_interpret(tree->left, env_ptr)->tree;
357
+    TOKEN* rhs = (TOKEN*) recursive_interpret(tree->right, env_ptr)->tree;
358
+    int result = lhs->value != rhs->value;
359
+    return anon_binding((NODE*) get_int_token(result));
325
   }
360
   }
326
   if (tree->type == '>') {
361
   if (tree->type == '>') {
327
-    return (int)recursive_interpret(tree->left, env_ptr) > recursive_interpret(tree->right, env_ptr);
362
+    TOKEN* lhs = (TOKEN*) recursive_interpret(tree->left, env_ptr)->tree;
363
+    TOKEN* rhs = (TOKEN*) recursive_interpret(tree->right, env_ptr)->tree;
364
+    int result = lhs->value > rhs->value;
365
+    return anon_binding((NODE*) get_int_token(result));
328
   }
366
   }
329
   if (tree->type == '<') {
367
   if (tree->type == '<') {
330
-    return (int)recursive_interpret(tree->left, env_ptr) < recursive_interpret(tree->right, env_ptr);
368
+    TOKEN* lhs = (TOKEN*) recursive_interpret(tree->left, env_ptr)->tree;
369
+    TOKEN* rhs = (TOKEN*) recursive_interpret(tree->right, env_ptr)->tree;
370
+    int result = lhs->value < rhs->value;
371
+    return anon_binding((NODE*) get_int_token(result));
331
   }
372
   }
332
   if (tree->type == '+') {
373
   if (tree->type == '+') {
333
-    return recursive_interpret(tree->left, env_ptr) + recursive_interpret(tree->right, env_ptr);
374
+    TOKEN* lhs = (TOKEN*) recursive_interpret(tree->left, env_ptr)->tree;
375
+    TOKEN* rhs = (TOKEN*) recursive_interpret(tree->right, env_ptr)->tree;
376
+    if (debug) printf("Adding %d and %d\n", lhs->value, rhs->value);
377
+    int result = lhs->value + rhs->value;
378
+    return anon_binding((NODE*) get_int_token(result));
334
   }
379
   }
335
   if (tree->type == '-') {
380
   if (tree->type == '-') {
336
-    return recursive_interpret(tree->left, env_ptr) - recursive_interpret(tree->right, env_ptr);
381
+    TOKEN* lhs = (TOKEN*) recursive_interpret(tree->left, env_ptr)->tree;
382
+    TOKEN* rhs = (TOKEN*) recursive_interpret(tree->right, env_ptr)->tree;
383
+    int result = lhs->value - rhs->value;
384
+    return anon_binding((NODE*) get_int_token(result));
337
   }
385
   }
338
   if (tree->type == '*') {
386
   if (tree->type == '*') {
339
-    return recursive_interpret(tree->left, env_ptr) * recursive_interpret(tree->right, env_ptr);
387
+    TOKEN* lhs = (TOKEN*) recursive_interpret(tree->left, env_ptr)->tree;
388
+    TOKEN* rhs = (TOKEN*) recursive_interpret(tree->right, env_ptr)->tree;
389
+    int result = lhs->value * rhs->value;
390
+    return anon_binding((NODE*) get_int_token(result));
340
   }
391
   }
341
   if (tree->type == '/') {
392
   if (tree->type == '/') {
342
-    return recursive_interpret(tree->left, env_ptr) / recursive_interpret(tree->right, env_ptr);
393
+    TOKEN* lhs = (TOKEN*) recursive_interpret(tree->left, env_ptr)->tree;
394
+    TOKEN* rhs = (TOKEN*) recursive_interpret(tree->right, env_ptr)->tree;
395
+    int result = lhs->value / rhs->value;
396
+    return anon_binding((NODE*) get_int_token(result));
343
   }
397
   }
344
   if (tree->type == '%') {
398
   if (tree->type == '%') {
345
-    return recursive_interpret(tree->left, env_ptr) % recursive_interpret(tree->right, env_ptr);
399
+    TOKEN* lhs = (TOKEN*) recursive_interpret(tree->left, env_ptr)->tree;
400
+    TOKEN* rhs = (TOKEN*) recursive_interpret(tree->right, env_ptr)->tree;
401
+    int result = lhs->value % rhs->value;
402
+    return anon_binding((NODE*) get_int_token(result));
346
   }
403
   }
347
   if (tree->type == '~') {
404
   if (tree->type == '~') {
348
     if (tree->left->type == INT || tree->left->type == FUNCTION) {
405
     if (tree->left->type == INT || tree->left->type == FUNCTION) {
353
     }
410
     }
354
   }
411
   }
355
   if (tree->type == RETURN) {
412
   if (tree->type == RETURN) {
356
-    return recursive_interpret(tree->left, env_ptr);
413
+    ret_val = recursive_interpret(tree->left, env_ptr);
414
+    returning = 1;
357
   }
415
   }
358
   if (tree->type == WHILE) {
416
   if (tree->type == WHILE) {
359
     ENV* scope_env = create_new_function_env(env_ptr);
417
     ENV* scope_env = create_new_function_env(env_ptr);
360
-    while (recursive_interpret(tree->left, env_ptr)) {
418
+    while(((TOKEN*)recursive_interpret(tree->left, env_ptr)->tree)->value == 1) {
361
       recursive_interpret(tree->right, scope_env);
419
       recursive_interpret(tree->right, scope_env);
362
     }
420
     }
363
     return 0;
421
     return 0;
381
   }
439
   }
382
   // print ref_main to make sure we really got it
440
   // print ref_main to make sure we really got it
383
   printf("Located %s, ready to run!\n", ref_main->name->lexeme);
441
   printf("Located %s, ready to run!\n", ref_main->name->lexeme);
384
-  printf("%d\n", recursive_interpret(ref_main->tree->right, ref_main->env));
442
+  recursive_interpret(ref_main->tree->right, ref_main->env);
443
+  /* printf("%d\n", ((TOKEN*)recursive_interpret(ref_main->tree->right, ref_main->env))->value); */
444
+  printf("%d\n", ((TOKEN*)ret_val->tree)->value);
385
 }
445
 }
386
 
446
 
387
 extern int yydebug;
447
 extern int yydebug;
392
 int main(int argc, char** argv)
452
 int main(int argc, char** argv)
393
 {
453
 {
394
     NODE* tree;
454
     NODE* tree;
395
-    if (argc>1 && strcmp(argv[1],"-d")==0) yydebug = 1;
455
+    if (argc>1 && strcmp(argv[1],"-d")==0) debug = 1;
396
     init_symbtable();
456
     init_symbtable();
397
     printf("--C COMPILER\n");
457
     printf("--C COMPILER\n");
398
     yyparse();
458
     yyparse();

+ 9 - 14
cw/simple.c

1
-int sum(int a, int b, int c) {
2
-  int y = 0;
3
-  if (a > 2) {
4
-    int x = 3;
5
-    y = x;
6
-  }
7
-  return y + b + c;
1
+int whammy(int a) {
2
+  return a + 5;
8
 }
3
 }
9
 
4
 
10
-int fact(int n) {
11
-  int inner_fact(int n, int a) {
12
-    if (n == 0) return a;
13
-    return inner_fact(n-1, a*n);
14
-  }
15
-  return inner_fact(n, 1);
5
+function twice(function f) {
6
+  int g(int x) { return f(f(x)); }
7
+  return g;
16
 }
8
 }
17
 
9
 
18
 int main() {
10
 int main() {
19
-  return fact(3);
11
+  x = twice(whammy);
12
+
13
+  return x(2);
20
 }
14
 }
15
+

+ 3 - 0
cw/tests/cond_loop.c

1
+/* ##answer: 17*/
1
 int y = 0;
2
 int y = 0;
2
 
3
 
3
 int incr_one() {
4
 int incr_one() {
4
   y = y + 1;
5
   y = y + 1;
6
+  return 0;
5
 }
7
 }
6
 
8
 
7
 int incr_two() {
9
 int incr_two() {
8
   y = y + 2;
10
   y = y + 2;
11
+  return 0;
9
 }
12
 }
10
 
13
 
11
 int main() {
14
 int main() {

+ 17 - 0
cw/tests/cplus.c

1
+/* ##answer: 29 */
2
+function cplus(int a) {
3
+  int cplusa(int b) {
4
+    return a + b;
5
+  }
6
+
7
+  return cplusa;
8
+}
9
+
10
+int main() {
11
+  int x = cplus(5);
12
+  int y = x;
13
+  int f = cplus(2);
14
+  int z = y;
15
+
16
+  return x(2) + f(2) + y(5) + z(3);
17
+}

+ 1 - 4
cw/tests/func_args.c

1
+/* ##answer: 14 */
1
 int y = 0;
2
 int y = 0;
2
 
3
 
3
 int incr_y(int a, int b) {
4
 int incr_y(int a, int b) {
8
   y = 2;
9
   y = 2;
9
 }
10
 }
10
 
11
 
11
-/* int blah2(int a, int b, int c, int d) {} */
12
-
13
-/* int blah3(int a) {} */
14
-
15
 int main() {
12
 int main() {
16
   incr_y(2,3);
13
   incr_y(2,3);
17
   incr_y(4, 5);
14
   incr_y(4, 5);

+ 2 - 0
cw/tests/func_call.c

1
+/* ##answer: 8*/
2
+
1
 int foo() {
3
 int foo() {
2
   return 5;
4
   return 5;
3
 }
5
 }

+ 4 - 0
cw/tests/modulo.c

1
+/* ##answer: 1*/
2
+int main() {
3
+  return 5 % 2; 
4
+}

+ 37 - 0
cw/tests/new_test.sh

1
+#!/bin/bash
2
+uname=`uname`
3
+if [ "$uname" = "Darwin" ]; then
4
+  date="gdate"
5
+  readlink="greadlink"
6
+else
7
+  date="date"
8
+  readlink="readlink"
9
+fi
10
+start=$($date +%s.%N)
11
+absdir=$($readlink -f $(dirname $0))
12
+
13
+pass="\033[32mPASSED\033[0m"
14
+fail="\033[31mFAILED\033[0m"
15
+
16
+tests=0
17
+passes=0
18
+
19
+for i in $(ls $absdir | grep .\*.c | sort); do
20
+  answer=`$absdir/../mycc < $absdir/$i | tail -n 1`
21
+  exp_ans=`grep --color=none "##answer" $absdir/$i | sed 's/[^0-9]\+\([0-9]\+\).\+/\1/g'`
22
+  echo -n "${i%.*} ... "
23
+  if [ "$answer" -eq "$exp_ans" ]; then
24
+    echo -e "$pass"
25
+    passes=$((passes+1))
26
+  else
27
+    echo -e "$fail expected $exp_ans got $answer"
28
+  fi
29
+  tests=$((tests+1))
30
+done
31
+
32
+end=$($date +%s.%N)    
33
+runtime=$(python -c "print(${end} - ${start})")
34
+
35
+echo -e "\n$passes/$tests passed in $runtime""s"
36
+
37
+exit $((tests-passes))

+ 17 - 0
cw/tests/recursion.c

1
+/* ##answer: 5166*/
2
+
3
+int fact(int n) {
4
+  int inner_fact(int n, int a) {
5
+    if (n == 0) return a;
6
+    return inner_fact(n-1, a*n);
7
+  }
8
+  return inner_fact(n, 1);
9
+}
10
+
11
+int main() {
12
+  int x = fact(3);
13
+  int y = fact(5);
14
+  int z = fact(7);
15
+
16
+  return x+y+z;
17
+}

+ 1 - 0
cw/tests/return_only.c

1
+/* ##answer: 3*/
1
 int main() {
2
 int main() {
2
   return 1 + 2;
3
   return 1 + 2;
3
 }
4
 }

+ 4 - 0
cw/tests/sub.c

1
+/* ##answer: 5 */
2
+int main() {
3
+  return 10 - 5;
4
+}

+ 25 - 52
cw/tests/test.sh

1
-#/bin/bash
1
+#!/bin/bash
2
 uname=`uname`
2
 uname=`uname`
3
-if [[ "$uname" -eq "Darwin" ]]; then
3
+if [ "$uname" = "Darwin" ]; then
4
   date="gdate"
4
   date="gdate"
5
   readlink="greadlink"
5
   readlink="greadlink"
6
+  wc="gwc"
6
 else
7
 else
7
   date="date"
8
   date="date"
8
   readlink="readlink"
9
   readlink="readlink"
10
+  wc="wc"
9
 fi
11
 fi
10
 start=$($date +%s.%N)
12
 start=$($date +%s.%N)
11
 absdir=$($readlink -f $(dirname $0))
13
 absdir=$($readlink -f $(dirname $0))
12
-ret_only=`$absdir/../mycc < $absdir/return_only.c | tail -n 1`
13
-var_maths=`$absdir/../mycc < $absdir/var_maths.c | tail -n 1`
14
-func_call=`$absdir/../mycc < $absdir/func_call.c | tail -n 1`
15
-cond_loop=`$absdir/../mycc < $absdir/cond_loop.c | tail -n 1`
16
-func_args=`$absdir/../mycc < $absdir/func_args.c | tail -n 1`
17
-
18
-ret_ans='3'
19
-var_ans='11'
20
-func_ans='8'
21
-args_ans='14'
22
-cond_ans='17'
23
-
24
-overall='0'
25
 
14
 
26
 pass="\033[32mPASSED\033[0m"
15
 pass="\033[32mPASSED\033[0m"
27
 fail="\033[31mFAILED\033[0m"
16
 fail="\033[31mFAILED\033[0m"
28
 
17
 
29
-if [[ "$ret_only" -eq $ret_ans ]]; then
30
-  echo "return_only ... $pass"
31
-else
32
-  echo -n "return_only ... $fail"
33
-  echo " expected $ret_ans but got $ret_only"
34
-  overall='1'
35
-fi
36
-if [[ "$var_maths" -eq $var_ans ]]; then
37
-  echo "var_maths ..... $pass"
38
-else
39
-  echo "var_maths ..... $fail"
40
-  echo " expected $var_ans but got $var_maths"
41
-  overall='1'
42
-fi
43
-if [[ "$func_call" -eq $func_ans ]]; then
44
-  echo "func_call ..... $pass"
45
-else
46
-  echo -n "func_call ..... $fail"
47
-  echo " expected $func_ans but got $func_call"
48
-  overall='1'
49
-fi
50
-if [[ "$cond_loop" -eq $cond_ans ]]; then
51
-  echo "cond_loop ..... $pass"
52
-else
53
-  echo -n "cond_loop ..... $fail"
54
-  echo " expected $cond_ans but got $cond_loop"
55
-  overall='1'
56
-fi
57
-if [[ "$func_args" -eq $args_ans ]]; then
58
-  echo "func_args ..... $pass"
59
-else
60
-  echo -n "func_args ..... $fail"
61
-  echo " expected $args_ans but got $func_args"
62
-  overall='1'
63
-fi
18
+tests=0
19
+passes=0
20
+
21
+num=`ls $absdir | grep .\*.c | $wc -L`
22
+num=$((num-2))
23
+fmt=`echo "%-$num""s"`
24
+for i in $(ls $absdir | grep .\*.c | sort); do
25
+  answer=`$absdir/../mycc < $absdir/$i | tail -n 1`
26
+  exp_ans=`grep --color=none "##answer" $absdir/$i | sed 's/[^0-9]\+\([0-9]\+\).\+/\1/g'`
27
+  printf $fmt "${i%.*}"
28
+  echo -n " ... "
29
+  if [ "$answer" -eq "$exp_ans" ]; then
30
+    echo -e "$pass"
31
+    passes=$((passes+1))
32
+  else
33
+    echo -e "$fail expected $exp_ans got $answer"
34
+  fi
35
+  tests=$((tests+1))
36
+done
64
 
37
 
65
 end=$($date +%s.%N)    
38
 end=$($date +%s.%N)    
66
 runtime=$(python -c "print(${end} - ${start})")
39
 runtime=$(python -c "print(${end} - ${start})")
67
 
40
 
68
-echo "\nCompleted 5 tests in $runtime""s"
41
+echo -e "\n$passes/$tests passed in $runtime""s"
69
 
42
 
70
-exit $overall
43
+exit $((tests-passes))

+ 16 - 0
cw/tests/twice.c

1
+/* ##answer: 12*/
2
+int whammy(int a) {
3
+  return a + 5;
4
+}
5
+
6
+function twice(function f) {
7
+  int g(int x) { return f(f(x)); }
8
+  return g;
9
+}
10
+
11
+int main() {
12
+  x = twice(whammy);
13
+
14
+  return x(2);
15
+}
16
+

+ 1 - 0
cw/tests/var_maths.c

1
+/* ##answer: 11*/
1
 int main() {
2
 int main() {
2
   int x = 5;
3
   int x = 5;
3
 
4
 

+ 1 - 0
cw/types.h

15
 
15
 
16
 typedef struct environ {
16
 typedef struct environ {
17
   BLIST *bindings;
17
   BLIST *bindings;
18
+  NODE *ret_val;
18
   struct environ *parent;
19
   struct environ *parent;
19
 } ENV;
20
 } ENV;
20
 
21