Started work on an AST inspector

This commit is contained in:
2026-04-22 15:57:43 +10:00
parent 63dfd33e5e
commit accb7f9fb4
7 changed files with 166 additions and 5 deletions
+100
View File
@@ -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 <stdio.h>
#include <stdlib.h>
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");
}
+5
View File
@@ -0,0 +1,5 @@
#pragma once
#include "toy_ast.h"
void inspect_ast(Toy_Ast* astHandle);
-5
View File
@@ -11,11 +11,6 @@
int inspect_instruction(unsigned char* bytecode, unsigned int pc, unsigned int jumps_addr, unsigned int data_addr); 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); 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 ISPRINT_SANITIZE(x) (isprint((int)x) > 0 ? (x) : '_')
#define MARKER_VALUE(pc, type) \ #define MARKER_VALUE(pc, type) \
+11
View File
@@ -1,3 +1,4 @@
#include "ast_inspector.h"
#include "bytecode_inspector.h" #include "bytecode_inspector.h"
#include "toy_console_colors.h" #include "toy_console_colors.h"
@@ -377,6 +378,11 @@ int repl(const char* filepath, bool verbose) {
printf("%s> ", prompt); //shows the terminal prompt printf("%s> ", prompt); //shows the terminal prompt
continue; continue;
} }
if (verbose) {
inspect_ast(ast);
}
unsigned char* bytecode = Toy_compileToBytecode(ast); unsigned char* bytecode = Toy_compileToBytecode(ast);
if (verbose) { if (verbose) {
@@ -473,6 +479,11 @@ int main(int argc, const char* argv[]) {
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL); Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
Toy_Ast* ast = Toy_scanParser(&bucket, &parser); Toy_Ast* ast = Toy_scanParser(&bucket, &parser);
if (cmd.verbose) {
inspect_ast(ast);
}
unsigned char* bytecode = Toy_compileToBytecode(ast); unsigned char* bytecode = Toy_compileToBytecode(ast);
Toy_freeBucket(&bucket); Toy_freeBucket(&bucket);
free(source); free(source);
+10
View File
@@ -0,0 +1,10 @@
print "hello world";
print "hello world";
print "hello world";
{
print "hello world";
{
print "hello world";
}
}
+38
View File
@@ -266,3 +266,41 @@ void Toy_private_emitAstEnd(Toy_Bucket** bucketHandle, Toy_Ast** astHandle) {
(*astHandle) = tmp; (*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;
}
+2
View File
@@ -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_emitAstPass(Toy_Bucket** bucketHandle, Toy_Ast** astHandle);
void Toy_private_emitAstError(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); void Toy_private_emitAstEnd(Toy_Bucket** bucketHandle, Toy_Ast** astHandle);
const char* Toy_private_getAstTypeAsCString(Toy_AstType type);