Skip to content

Commit

Permalink
vm parser: implement macros
Browse files Browse the repository at this point in the history
  • Loading branch information
LBCrion committed Dec 17, 2024
1 parent bf76d13 commit e45f4b4
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 2 deletions.
3 changes: 2 additions & 1 deletion src/config/toplevel.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "module.h"
#include "gui/bar.h"
#include "gui/menu.h"
#include "vm/vm.h"

gboolean config_action_conditions ( GScanner *scanner, action_t *action )
{
Expand Down Expand Up @@ -358,7 +359,7 @@ GtkWidget *config_parse_toplevel ( GScanner *scanner, GtkWidget *container )
config_include(scanner, NULL);
break;
case G_TOKEN_DEFINE:
config_define(scanner);
parser_macro_add(scanner);
break;
case G_TOKEN_SET:
config_set(scanner);
Expand Down
51 changes: 50 additions & 1 deletion src/vm/parser.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@

#include "util/string.h"
#include "vm/vm.h"

static guint8 mark = EXPR_OP_MARK;
static GHashTable *macros;

static gint parser_emit_jump ( GByteArray *code, guint8 op )
{
Expand Down Expand Up @@ -163,6 +165,21 @@ static void parser_variable ( GScanner *scanner, GByteArray *code )
g_byte_array_append(code, data, sizeof(gpointer)+1);
}

static gboolean parser_macro_handle ( GScanner *scanner, GByteArray *code )
{
GBytes *bytes;
gsize len;
gconstpointer data;

if(!macros ||
!(bytes = g_hash_table_lookup(macros, scanner->value.v_identifier)) )
return FALSE;

data = g_bytes_get_data(bytes, &len);
g_byte_array_append(code, data, len);
return TRUE;
}

static gboolean parser_identifier ( GScanner *scanner, GByteArray *code )
{
if(!g_ascii_strcasecmp(scanner->value.v_identifier, "if"))
Expand All @@ -175,7 +192,7 @@ static gboolean parser_identifier ( GScanner *scanner, GByteArray *code )
parser_emit_numeric(code, FALSE);
else if(g_scanner_peek_next_token(scanner)=='(')
return parser_function(scanner, code);
else
else if(!parser_macro_handle(scanner, code))
parser_variable(scanner, code);

return TRUE;
Expand Down Expand Up @@ -273,6 +290,38 @@ gboolean parser_expr_parse ( GScanner *scanner, GByteArray *code )
return parser_ops(scanner, code, 0);
}

gboolean parser_macro_add ( GScanner *scanner )
{
GByteArray *code;
gchar *name;

if(g_scanner_get_next_token(scanner) != G_TOKEN_IDENTIFIER)
return FALSE;
name = g_strdup(scanner->value.v_identifier);
if(g_scanner_get_next_token(scanner) != '=')
{
g_free(name);
return FALSE;
}

code = g_byte_array_new();

if(!parser_expr_parse(scanner, code))
{
g_byte_array_free(code, TRUE);
g_free(name);
return FALSE;
}

if(!macros)
macros = g_hash_table_new_full( (GHashFunc)str_nhash,
(GEqualFunc)str_nequal, g_free, (GDestroyNotify)g_bytes_unref);

g_hash_table_insert(macros, name, g_byte_array_free_to_bytes(code));

return TRUE;
}

static GScanner *parser_scanner_new ( void )
{
GScanner *scanner;
Expand Down
1 change: 1 addition & 0 deletions src/vm/vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ typedef struct {

GByteArray *parser_expr_compile ( gchar *expr );
gboolean parser_expr_parse ( GScanner *scanner, GByteArray *code );
gboolean parser_macro_add ( GScanner *scanner );
value_t vm_expr_eval ( expr_cache_t *expr );
gchar *expr_vm_result_to_string ( vm_t *vm );
gint expr_vm_get_func_params ( vm_t *vm, value_t *params[] );
Expand Down

0 comments on commit e45f4b4

Please sign in to comment.