Scope works.
This commit is contained in:
		
							
								
								
									
										75
									
								
								src/exec.c
									
									
									
									
									
								
							
							
						
						
									
										75
									
								
								src/exec.c
									
									
									
									
									
								
							| @@ -33,61 +33,68 @@ ASTNumData exec_start(AST* ast) { | ||||
|     // Push global namespace to `scope`. | ||||
|     stack_push(scope, global); | ||||
|  | ||||
|     return exec_exp(ast, scope); | ||||
|     return exec_exp(ast); | ||||
| } | ||||
|  | ||||
| ASTNumData exec_exp(AST* ast, Stack* scope) { | ||||
| ASTNumData exec_exp(AST* ast) { | ||||
|     log_dbg("Started execution."); | ||||
|     switch (ast->type) { | ||||
|         case AST_TYPE_BLOCK: return exec_block(ast, scope); | ||||
|         case AST_TYPE_CALL:  return exec_call(ast, scope); | ||||
|         case AST_TYPE_BLOCK: return exec_block(ast); | ||||
|         case AST_TYPE_CALL:  return exec_call(ast); | ||||
|         case AST_TYPE_NUM:   return *(ASTNumData*)ast->data; | ||||
|         case AST_TYPE_VREF:  return exec_vref(ast, scope); | ||||
|         case AST_TYPE_VDEF:  return exec_vdef(ast, scope); | ||||
|         case AST_TYPE_VREF:  return exec_vref(ast); | ||||
|         case AST_TYPE_VDEF:  return exec_vdef(ast); | ||||
|         default:             printf("what\n"); exit(1); | ||||
|     } | ||||
| } | ||||
|  | ||||
| ASTNumData exec_block(AST* ast, Stack* scope) { | ||||
| ASTNumData exec_block(AST* ast) { | ||||
|     ASTBlockData* block = (ASTBlockData*)ast->data; | ||||
|  | ||||
|     // Loop through all but last ast. | ||||
|     for (int i = 0; i < block->ln - 1; i++) exec_exp(block->inside[i], scope); | ||||
|     HTab* local = htab_init(); | ||||
|     stack_push(scope, local); | ||||
|  | ||||
|     return exec_exp(block->inside[block->ln - 1], scope); | ||||
|     // Loop through all but last ast. | ||||
|     for (int i = 0; i < block->ln - 1; i++) exec_exp(block->inside[i]); | ||||
|     ASTNumData last = exec_exp(block->inside[block->ln - 1]); | ||||
|  | ||||
|     stack_pop(scope); | ||||
|     htab_destroy(local); | ||||
|  | ||||
|     return last; | ||||
| } | ||||
|  | ||||
| ASTNumData exec_call(AST* ast, Stack* scope) { | ||||
| ASTNumData exec_call(AST* ast) { | ||||
|     log_dbg("Started call execution."); | ||||
|     fflush(stdout); | ||||
|     ASTCallData* calldata = (ASTCallData*)ast->data; | ||||
|     if (calldata->argc >= 1) { | ||||
|         if (!strcmp(calldata->to, "sum")) { | ||||
|             double total = exec_exp(calldata->argv[0], scope); | ||||
|             double total = exec_exp(calldata->argv[0]); | ||||
|  | ||||
|             for (size_t i = 1; i < calldata->argc; | ||||
|                  total += exec_exp(calldata->argv[i++], scope)); | ||||
|                  total += exec_exp(calldata->argv[i++])); | ||||
|  | ||||
|             return total; | ||||
|         } else if (!strcmp(calldata->to, "sub")) { | ||||
|             double total = exec_exp(calldata->argv[0], scope); | ||||
|             double total = exec_exp(calldata->argv[0]); | ||||
|  | ||||
|             for (size_t i = 1; i < calldata->argc; | ||||
|                  total -= exec_exp(calldata->argv[i++], scope)); | ||||
|                  total -= exec_exp(calldata->argv[i++])); | ||||
|  | ||||
|             return total; | ||||
|         } else if (!strcmp(calldata->to, "mul")) { | ||||
|             double total = exec_exp(calldata->argv[0], scope); | ||||
|             double total = exec_exp(calldata->argv[0]); | ||||
|  | ||||
|             for (size_t i = 1; i < calldata->argc; | ||||
|                  total *= exec_exp(calldata->argv[i++], scope)); | ||||
|                  total *= exec_exp(calldata->argv[i++])); | ||||
|  | ||||
|             return total; | ||||
|         } else if (!strcmp(calldata->to, "div")) { | ||||
|             double total = exec_exp(calldata->argv[0], scope); | ||||
|             double total = exec_exp(calldata->argv[0]); | ||||
|  | ||||
|             for (size_t i = 1; i < calldata->argc; | ||||
|                  total /= exec_exp(calldata->argv[i++], scope)); | ||||
|                  total /= exec_exp(calldata->argv[i++])); | ||||
|  | ||||
|             return total; | ||||
|         } | ||||
| @@ -95,26 +102,32 @@ ASTNumData exec_call(AST* ast, Stack* scope) { | ||||
|     return -1000; | ||||
| } | ||||
|  | ||||
| ASTNumData exec_vdef(AST* ast, Stack* scope) { | ||||
| AST* exec_find(char* name) { | ||||
|     AST* val = NULL; | ||||
|  | ||||
|     for (int i = scope->ln - 1; i >= 0; i--) { | ||||
|         HTab* lvl = scope->buf[i]; | ||||
|         val = htab_get(lvl, name); | ||||
|         if (val != NULL) return val; | ||||
|     } | ||||
|  | ||||
|     log_dbgf("Could not find var %s", name); | ||||
|     exit(1); | ||||
| } | ||||
|  | ||||
| ASTNumData exec_vdef(AST* ast) { | ||||
|     ASTVDefData* data = (ASTVDefData*)ast->data; | ||||
|     AST* val = data->val; | ||||
|     char* key = data->name; | ||||
|     htab_ins(scope->val[0], key, val); | ||||
|     return exec_exp(val, scope); | ||||
|     htab_ins(scope->buf[scope->ln - 1], key, val); | ||||
|     return exec_exp(val); | ||||
| } | ||||
|  | ||||
| ASTNumData exec_vref(AST* ast, Stack* scope) { | ||||
| ASTNumData exec_vref(AST* ast) { | ||||
|     log_dbg("attempting to reference var"); | ||||
|     ASTVrefData* vref = (ASTVrefData*)ast->data; | ||||
|  | ||||
|     char* key = vref->to; | ||||
|     AST* val; | ||||
|  | ||||
|     val = htab_get(scope->val[0], key); | ||||
|     if (val != NULL) return exec_exp(val, scope); | ||||
|     else log_dbg("didn't find def"); | ||||
|  | ||||
|     return *ast_num_data_init(101.0); | ||||
|     return exec_exp(exec_find(vref->to)); | ||||
| } | ||||
|  | ||||
| void exec_print(double n) { printf("= %lf\n", n); } | ||||
|   | ||||
| @@ -196,3 +196,4 @@ exp: | ||||
|         $$ = ast_init(AST_TYPE_CALL, ast_call_data_init(to, 2, argv)); | ||||
|     } | ||||
| %% | ||||
|  | ||||
|   | ||||
| @@ -9,11 +9,11 @@ extern Stack* scope; | ||||
|  | ||||
| // Start executing at the root of the AST. Initialize the `scope`. | ||||
| ASTNumData exec_start(AST* ast); | ||||
| ASTNumData exec_exp(AST* ast, Stack* scope); | ||||
| ASTNumData exec_block(AST* ast, Stack* scope); | ||||
| ASTNumData exec_call(AST* ast, Stack* scope); | ||||
| ASTNumData exec_vref(AST* ast, Stack* scope); | ||||
| ASTNumData exec_vdef(AST* ast, Stack* scope); | ||||
| ASTNumData exec_exp(AST* ast); | ||||
| ASTNumData exec_block(AST* ast); | ||||
| ASTNumData exec_call(AST* ast); | ||||
| ASTNumData exec_vref(AST* ast); | ||||
| ASTNumData exec_vdef(AST* ast); | ||||
| void exec_print(double n); | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -6,8 +6,8 @@ | ||||
| #define STACK_MAX 64 | ||||
|  | ||||
| typedef struct { | ||||
|     size_t i;               // Current index in the stack. | ||||
|     void* val[STACK_MAX];   // The stack itself. | ||||
|     size_t ln;            // The length of the stack (i.e., how many elements). | ||||
|     void* buf[STACK_MAX]; // The stack itself. | ||||
| } Stack; | ||||
|  | ||||
| // Create a `Stack`. | ||||
|   | ||||
							
								
								
									
										17
									
								
								src/stack.c
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								src/stack.c
									
									
									
									
									
								
							| @@ -8,33 +8,34 @@ | ||||
| Stack* stack_init() { | ||||
|     talloc(Stack, stack); | ||||
|  | ||||
|     memset(stack->val, 0, sizeof(void*) * STACK_MAX); | ||||
|     stack->i = 0; | ||||
|     memset(stack->buf, 0, sizeof(void*) * STACK_MAX); | ||||
|     stack->ln = 0; | ||||
|  | ||||
|     return stack; | ||||
| } | ||||
|  | ||||
| void stack_destroy(Stack* stack) { | ||||
|     // Can only free an empty stack. | ||||
|     assert(stack->i == 0); | ||||
|     assert(stack->ln == 0); | ||||
|     free(stack); | ||||
| } | ||||
|  | ||||
| void stack_push(Stack* stack, void* val) { | ||||
|     if (stack->i >= STACK_MAX) { | ||||
|     log_dbgf("pushed to stack, inc ln to %ld", stack->ln); | ||||
|     if (stack->ln >= STACK_MAX) { | ||||
|         log_dbgf("Ran out of stack (max: %d)", STACK_MAX); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     stack->val[stack->i] = val; | ||||
|     stack->i++; | ||||
|     stack->buf[stack->ln] = val; | ||||
|     stack->ln++; | ||||
| } | ||||
|  | ||||
| void* stack_pop(Stack* stack) { | ||||
|     if (stack->i <= 0) { | ||||
|     if (stack->ln <= 0) { | ||||
|         log_dbg("Can't pop empty stack."); | ||||
|         return (void*)-1; | ||||
|     } | ||||
|  | ||||
|     return stack->val[--stack->i]; | ||||
|     return stack->buf[--stack->ln]; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user