• Jump To … +
    CodeGen.cpp CodeGen.h ast.cpp ast.h main.cpp main.h parser.y tokens.l
  • ast.cpp

  • ¶
    #include "ast.h"
    #include "main.h"
  • ¶

    Return a string representing the struct type passed in

    const char *ast_type_str(ast_type type)
    {
    	switch (type.type)
    	{
    		case VAR_BOOL:
    			return "boolean";
    		case VAR_INT:
    			return "int";
    		case VAR_INT_ARRAY:
    			return "int[]";
    		case VAR_CLASS:
    			return type.classname;
    		case VAR_STRING_ARRAY:
    			return "String[]";
    		case VAR_VOID:
    			return "void";
    		default:
    			return "-- UNKNOWN TYPE --";
    	}
    }
  • ¶

    Map the id of the parent class to this in Method(this, arg1, arg2,..)

    void initialize_var_declaration_this(ast_methoddecl *class_methods, char* classname) {
    	for (ast_methoddecl *method=class_methods; method!=NULL; method = method->next) {
    		for (ast_vardecl *param = method->params; param!=NULL; param = param->next) {
    			if (param->id == "this") {
    				param->type.classname = classname;
    			}
    		}
    	}
    }
  • ¶

    Write to the file, the appropriate indent for the indent level

    void print_indent(FILE *file, int indent_level)
    {
    	int i;
    	for(i = 0; i < indent_level; ++i)
    		fputs("  ", file);
    }
  • ¶

    Print the ast_expr

    void ast_expr_print(FILE *file, int indent_level, ast_expr *expr)
    {
    	if(expr == NULL)
    		return; // If ExpList is empty, print nothing
    	print_indent(file, indent_level);
    
    	char *op_str;
    
    	switch(expr->type)
    	{
    		case INT_CONST:
    			fprintf(file, "INT_CONST(%d)\n", expr->int_const);
    			break;
    		case BOOL_CONST:
    			fprintf(file, "BOOL_CONST(%s)\n", expr->bool_const ? "true" : "false");
    			break;
    		case VARNAME:
    			fprintf(file, "VARNAME(%s)\n", expr->id);
    			break;
    		case THIS_PTR:
    			fprintf(file, "THIS_PTR\n");
    			break;
    		case NOT_EXPR:
    			fprintf(file, "NOT_EXPR:\n");
    				ast_expr_print(file, indent_level + 1, expr->expr);
    			break;
    		case NEW_CLASS:
    			fprintf(file, "NEW_CLASS(%s)\n", expr->id);
    			break;
    		case NEW_INT_ARRAY:
    			fprintf(file, "NEW_INT_ARRAY[\n");
    				ast_expr_print(file, indent_level + 1, expr->expr);
    			print_indent(file, indent_level);
    			fprintf(file, "]\n");
    			break;
    		case ARRAY_LENGTH:
    			fprintf(file, "ARRAY_LENGTH:\n");
    				ast_expr_print(file, indent_level + 1, expr->expr);
    			break;
    		case ARRAY_INDEX:
    			fprintf(file, "ARRAY_INDEX:\n");
    				ast_expr_print(file, indent_level + 1, expr->array);
    			print_indent(file, indent_level+1);
    			fprintf(file, "[\n");
    				ast_expr_print(file, indent_level + 1, expr->array_index);
    			print_indent(file, indent_level+1);
    			fprintf(file, "]\n");
    			break;
    		case METHOD_CALL:
    			fprintf(file, "METHOD_CALL(%s):\n", expr->method);
    			print_indent(file, indent_level + 1);
    			fprintf(file, "OBJECT:\n");
    				ast_expr_print(file, indent_level + 2, expr->object);
    			print_indent(file, indent_level + 1);
    			fprintf(file, "EXP_LIST:\n");
    				ast_expr_print(file, indent_level + 2, expr->exp_list);
    			break;
    		case BINOP:
    			switch(expr->oper) {
    				case AND:
    					op_str = "AND";
    					break;
    				case LESS:
    					op_str = "LESS";
    					break;
    				case PLUS:
    					op_str = "PLUS";
    					break;
    				case MINUS:
    					op_str = "MINUS";
    					break;
    				case MULT:
    					op_str = "MULT";
    					break;
    				default:
    					op_str = "--- UNKNOWN OPERAND ---";
    					break;
    			}
    			fprintf(file, "BINOP(%s):\n", op_str);
    			print_indent(file, indent_level + 1);
    			fprintf(file, "LHS:\n");
    				ast_expr_print(file, indent_level + 2, expr->lhs);
    			print_indent(file, indent_level + 1);
    			fprintf(file, "RHS:\n");
    				ast_expr_print(file, indent_level + 2, expr->rhs);
    			break;
    		default:
    			fprintf(file, "--- UNKNOWN EXPRESSION ---\n");
    			break;
    	}
    	if(expr->next != NULL) // ExpList
    		ast_expr_print(file, indent_level, expr->next);
    }
  • ¶

    Print the ast struct ast_stmt. This prints all statements list by looping through the linked list ->next reference

    void ast_stmt_print(FILE *file, int indent_level, ast_stmt *stmt)
    {
    	if(stmt == NULL)
    		return; // If StmtList is empty, print nothing.
    	print_indent(file, indent_level);
    
    	switch(stmt->type)
    	{
    		case BLOCK:
    			fputs("BLOCK:\n", file);
    				ast_stmt_print(file, indent_level+1, stmt->stmt_list);
    			break;
    		case IF_ELSE:
    			fprintf(file, "IF_ELSE:\n");
    			print_indent(file, indent_level + 1);
    			fprintf(file, "COND:\n");
    				ast_expr_print(file, indent_level+2, stmt->cond);
    			print_indent(file, indent_level + 1);
    			fprintf(file, "TRUE:\n");
    				ast_stmt_print(file, indent_level+2, stmt->true_branch);
    			print_indent(file, indent_level + 1);
    			fprintf(file, "FALSE:\n");
    				ast_stmt_print(file, indent_level+2, stmt->false_branch);
    			break;
    		case WHILE_STMT:
    			fprintf(file, "WHILE_STMT:\n");
    			print_indent(file, indent_level + 1);
    			fprintf(file, "COND:\n");
    				ast_expr_print(file, indent_level+2, stmt->cond);
    			print_indent(file, indent_level + 1);
    			fprintf(file, "WHILE_TRUE:\n");
    				ast_stmt_print(file, indent_level+2, stmt->while_branch);
    			break;
    		case SYS_OUT:
    			fprintf(file, "SYS_OUT:\n");
    				ast_expr_print(file, indent_level + 1, stmt->expr);
    			break;
    		case VAR_ASSIGN:
    			fprintf(file, "VAR_ASSIGN(%s):\n", stmt->id);
    			print_indent(file, indent_level + 1);
    			fprintf(file, "EXPRESSION:\n");
    				ast_expr_print(file, indent_level + 2, stmt->assign_expr);
    			break;
    		case ARRAY_ASSIGN:
    			fprintf(file, "ARRAY_ASSIGN(%s):\n", stmt->id);
    			print_indent(file, indent_level + 1);
    			fprintf(file, "INDEX:\n");
    				ast_expr_print(file, indent_level + 2, stmt->array_index);
    			print_indent(file, indent_level + 1);
    			fprintf(file, "EXPRESSION:\n");
    				ast_expr_print(file, indent_level + 2, stmt->assign_expr);
    			break;
    		default:
    			fprintf(file, "--- UNKNOWN STATEMENT ---\n");
    			break;
    	}
    	if(stmt->next != NULL) // StmtList
    		ast_stmt_print(file, indent_level, stmt->next);
    }
  • ¶

    Print the ast struct ast_vardecl. This prints all variable declarations by looping through the linked list ->next reference

    void ast_vardecl_print(FILE *file, int indent_level, ast_vardecl *decl)
    {
    	if(decl == NULL)
    		return; // If VarList is empty, print nothing.
    
    	print_indent(file, indent_level);
    	fprintf(file, "%s : %s\n", decl->id, ast_type_str(decl->type));
    
    	if(decl->next != NULL)
    		ast_vardecl_print(file, indent_level, decl->next);
    }
  • ¶

    Print the ast struct ast_methoddecl. This prints all method declarations by looping through the linked list ->next reference

    void ast_method_print(FILE *file, int indent_level, ast_methoddecl *method)
    {
    	if(method == NULL)
    		return; // If MethodList is empty, print nothing.
    
    	print_indent(file, indent_level);
    	fprintf(file, "MethodDeclaration(%s : %s):\n", method->id, ast_type_str(method->type));
    	print_indent(file, indent_level + 1);
    	fprintf(file, "PARAMETERS:\n");
    		ast_vardecl_print(file, indent_level + 2, method->params);
    	print_indent(file, indent_level + 1);
    	fprintf(file, "VarDeclaration:\n");
    		ast_vardecl_print(file, indent_level + 2, method->var_decl);
    	print_indent(file, indent_level + 1);
    	fprintf(file, "BODY:\n");
    		ast_stmt_print(file, indent_level + 2, method->body);
    	print_indent(file, indent_level + 1);
    	fprintf(file, "RETURN:\n");
    		ast_expr_print(file, indent_level + 2, method->return_expr);
    
    	if(method->next != NULL) // StmtList
    		ast_method_print(file, indent_level, method->next);
    }
  • ¶

    Print the ast struct ast_classdecl. This prints all class declarations by looping through the linked list ->next reference

    void ast_class_print(FILE *file, int indent_level, ast_classdecl *class_declaration)
    {
    	if(class_declaration == NULL)
    		return; // If MethodList is empty, print nothing.
    
    	print_indent(file, indent_level);
    	fprintf(file, "ClassDeclaration(%s):\n", class_declaration->id);
    	print_indent(file, indent_level + 1);
    	fprintf(file, "FIELDS:\n");
    		ast_vardecl_print(file, indent_level + 2, class_declaration->fields);
    	print_indent(file, indent_level + 1);
    	fprintf(file, "METHODS:\n");
    		ast_method_print(file, indent_level + 2, class_declaration->methods);
    
    	if(class_declaration->next != NULL) // StmtList
    		ast_class_print(file, indent_level, class_declaration->next);
    }
  • ¶

    Print the ast struct ast_mainclass

    void ast_main_print(FILE *file, int indent_level, ast_mainclass *main_class)
    {
    	print_indent(file, indent_level);
    	fprintf(file, "MainClass(%s):\n", main_class->id);
    		ast_method_print(file, indent_level + 1, main_class->method);
    }
  • ¶

    Print our AST

    void ast_program_print(FILE *file, int indent_level, ast_program *program)
    {
    	print_indent(file, indent_level);
    	fprintf(file, "PROGRAM:\n");
    		ast_main_print(file, indent_level + 1, &program->main_class);
    	print_indent(file, indent_level + 1);
    	fprintf(file, "CLASSES:\n");
    		ast_class_print(file, indent_level + 2, program->class_list);
    }