diff --git a/repl/ast_inspector.c b/repl/ast_inspector.c new file mode 100644 index 0000000..458bfcd --- /dev/null +++ b/repl/ast_inspector.c @@ -0,0 +1,100 @@ +#include "ast_inspector.h" +#include "toy_console_colors.h" +#include "toy_bucket.h" +#include "toy_string.h" +#include "toy_value.h" + +#include +#include + +void inspect_by_type(Toy_Ast* ast, int depth); + +void inspect_block(Toy_Ast* ast, int depth); +void inspect_value(Toy_Ast* ast, int depth); +void inspect_print(Toy_Ast* ast, int depth); + +#define PRINTSTR(x) printf("%*s%s", depth*4, "", x); + +static Toy_Bucket* bucket = NULL; //lazy + +void inspect_ast(Toy_Ast* ast) { + bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL); + inspect_by_type(ast, 0); + Toy_freeBucket(&bucket); +} + +void inspect_by_type(Toy_Ast* ast, int depth) { + switch(ast->type) { + case TOY_AST_BLOCK: + inspect_block(ast, depth); + return; + + case TOY_AST_VALUE: + inspect_value(ast, depth); + return; + // case TOY_AST_UNARY: + // case TOY_AST_BINARY: + // case TOY_AST_BINARY_SHORT_CIRCUIT: + // case TOY_AST_COMPARE: + // case TOY_AST_GROUP: + // case TOY_AST_COMPOUND: + // case TOY_AST_AGGREGATE: + + // case TOY_AST_ASSERT: + // case TOY_AST_IF_THEN_ELSE: + // case TOY_AST_WHILE_THEN: + // case TOY_AST_BREAK: + // case TOY_AST_CONTINUE: + // case TOY_AST_RETURN: + case TOY_AST_PRINT: + inspect_print(ast, depth); + return; + + // case TOY_AST_VAR_DECLARE: + // case TOY_AST_VAR_ASSIGN: + // case TOY_AST_VAR_ACCESS: + + // case TOY_AST_FN_DECLARE: + // case TOY_AST_FN_INVOKE: + + // case TOY_AST_STACK_POP: + + default: + printf(TOY_CC_WARN "%*sAST %s (unhandled by inspector)" TOY_CC_RESET "\n", depth*4, "", Toy_private_getAstTypeAsCString(ast->type)); + } +} + +void inspect_block(Toy_Ast* ast, int depth) { + //show the block braces + PRINTSTR("{\n"); + + if (ast->block.child) { + inspect_by_type(ast->block.child, depth + 1); + + if (ast->block.next) { + inspect_block(ast->block.next, depth + 0); + } + } + + PRINTSTR("}\n"); +} + +void inspect_value(Toy_Ast* ast, int depth) { + (void)depth; + Toy_String* str = Toy_stringifyValue(&bucket, ast->value.value); + + char* buffer = Toy_getStringRaw(str); //SLOW + printf("%s '%s'", Toy_private_getValueTypeAsCString(ast->value.value.type), buffer); + free(buffer); + + Toy_freeString(str); +} + +void inspect_print(Toy_Ast* ast, int depth) { + (void)depth; + PRINTSTR("PRINT "); + + inspect_by_type(ast->print.child, depth); + + printf(";\n"); +} \ No newline at end of file diff --git a/repl/ast_inspector.h b/repl/ast_inspector.h new file mode 100644 index 0000000..5ab017d --- /dev/null +++ b/repl/ast_inspector.h @@ -0,0 +1,5 @@ +#pragma once + +#include "toy_ast.h" + +void inspect_ast(Toy_Ast* astHandle); diff --git a/repl/bytecode_inspector.c b/repl/bytecode_inspector.c index 9dd3c4f..c772d2a 100644 --- a/repl/bytecode_inspector.c +++ b/repl/bytecode_inspector.c @@ -11,11 +11,6 @@ int inspect_instruction(unsigned char* bytecode, unsigned int pc, unsigned int jumps_addr, unsigned int data_addr); int inspect_read(unsigned char* bytecode, unsigned int pc, unsigned int jumps_addr, unsigned int data_addr); -// void inspect_jumps(unsigned char* bytecode, unsigned int pc, unsigned int size); -// void inspect_param(unsigned char* bytecode, unsigned int pc, unsigned int size); -// void inspect_data(unsigned char* bytecode, unsigned int pc, unsigned int size); -// void inspect_subs(unsigned char* bytecode, unsigned int pc, unsigned int size); - #define ISPRINT_SANITIZE(x) (isprint((int)x) > 0 ? (x) : '_') #define MARKER_VALUE(pc, type) \ diff --git a/repl/main.c b/repl/main.c index 5b60fc2..0a1dd8e 100644 --- a/repl/main.c +++ b/repl/main.c @@ -1,3 +1,4 @@ +#include "ast_inspector.h" #include "bytecode_inspector.h" #include "toy_console_colors.h" @@ -377,6 +378,11 @@ int repl(const char* filepath, bool verbose) { printf("%s> ", prompt); //shows the terminal prompt continue; } + + if (verbose) { + inspect_ast(ast); + } + unsigned char* bytecode = Toy_compileToBytecode(ast); if (verbose) { @@ -473,6 +479,11 @@ int main(int argc, const char* argv[]) { Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL); Toy_Ast* ast = Toy_scanParser(&bucket, &parser); + + if (cmd.verbose) { + inspect_ast(ast); + } + unsigned char* bytecode = Toy_compileToBytecode(ast); Toy_freeBucket(&bucket); free(source); diff --git a/scripts/blockhead.toy b/scripts/blockhead.toy new file mode 100644 index 0000000..4b30a5f --- /dev/null +++ b/scripts/blockhead.toy @@ -0,0 +1,10 @@ + +print "hello world"; +print "hello world"; +print "hello world"; +{ + print "hello world"; + { + print "hello world"; + } +} \ No newline at end of file diff --git a/source/toy_ast.c b/source/toy_ast.c index ad64536..3c823fa 100644 --- a/source/toy_ast.c +++ b/source/toy_ast.c @@ -266,3 +266,41 @@ void Toy_private_emitAstEnd(Toy_Bucket** bucketHandle, Toy_Ast** astHandle) { (*astHandle) = tmp; } + +const char* Toy_private_getAstTypeAsCString(Toy_AstType type) { + switch(type) { + case TOY_AST_BLOCK: return "BLOCK"; + + case TOY_AST_VALUE: return "VALUE"; + case TOY_AST_UNARY: return "UNARY"; + case TOY_AST_BINARY: return "BINARY"; + case TOY_AST_BINARY_SHORT_CIRCUIT: return "BINARY_SHORT_CIRCUIT"; + case TOY_AST_COMPARE: return "COMPARE"; + case TOY_AST_GROUP: return "GROUP"; + case TOY_AST_COMPOUND: return "COMPOUND"; + case TOY_AST_AGGREGATE: return "AGGREGATE"; + + case TOY_AST_ASSERT: return "ASSERT"; + case TOY_AST_IF_THEN_ELSE: return "IF_THEN_ELSE"; + case TOY_AST_WHILE_THEN: return "WHILE_THEN"; + case TOY_AST_BREAK: return "BREAK"; + case TOY_AST_CONTINUE: return "CONTINUE"; + case TOY_AST_RETURN: return "RETURN"; + case TOY_AST_PRINT: return "PRINT"; + + case TOY_AST_VAR_DECLARE: return "DECLARE"; + case TOY_AST_VAR_ASSIGN: return "ASSIGN"; + case TOY_AST_VAR_ACCESS: return "ACCESS"; + + case TOY_AST_FN_DECLARE: return "FN_DECLARE"; + case TOY_AST_FN_INVOKE: return "FN_INVOKE"; + + case TOY_AST_STACK_POP: return "STACK_POP"; + + case TOY_AST_PASS: return "PASS"; + case TOY_AST_ERROR: return "ERROR"; + case TOY_AST_END: return "END"; + } + + return NULL; +} \ No newline at end of file diff --git a/source/toy_ast.h b/source/toy_ast.h index cc8893f..f66176a 100644 --- a/source/toy_ast.h +++ b/source/toy_ast.h @@ -297,3 +297,5 @@ void Toy_private_emitAstStackPop(Toy_Bucket** bucketHandle, Toy_Ast** astHandle) void Toy_private_emitAstPass(Toy_Bucket** bucketHandle, Toy_Ast** astHandle); void Toy_private_emitAstError(Toy_Bucket** bucketHandle, Toy_Ast** astHandle); void Toy_private_emitAstEnd(Toy_Bucket** bucketHandle, Toy_Ast** astHandle); + +const char* Toy_private_getAstTypeAsCString(Toy_AstType type); \ No newline at end of file