Skip to content

Commit

Permalink
VM: add support for strings
Browse files Browse the repository at this point in the history
  • Loading branch information
mrunix00 committed Sep 12, 2024
1 parent 8011daa commit d471a9e
Show file tree
Hide file tree
Showing 7 changed files with 196 additions and 48 deletions.
11 changes: 11 additions & 0 deletions examples/strings.hal
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
globals: 0
global_pointers: 0
---
:0 { args: 0 ptr_args: 0 locals: 0 local_pointers: 0 } {
PushLiteralString "Hello,";
PushLiteralString " World!";
ConcatStrings;
PrintString;
Exit;
}
4 changes: 4 additions & 0 deletions include/assembler/lexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,12 @@ typedef enum
TOKEN_ModI64,
TOKEN_Call,
TOKEN_PrintTopStackI64,
TOKEN_PushLiteralString,
TOKEN_ConcatStrings,
TOKEN_PrintString,
TOKEN_Exit,
TOKEN_NUMBER,
TOKEN_STRING,
TOKEN_COLON,
TOKEN_SEMICOLON,
TOKEN_HASHTAG,
Expand Down
47 changes: 38 additions & 9 deletions include/hal64.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,34 @@ typedef enum
OP_MOD_I64,
OP_CALL,
OP_PRINT_TOP_STACK_I64,
OP_PUSH_LITERAL_STRING,
OP_CONCAT_STRINGS,
OP_PRINT_STRING,
OP_EXIT,
} InstructionOp;

typedef struct
{
InstructionOp op;
union {
union
{
uint64_t immediate;
size_t reg;
struct {
struct
{
size_t reg;
uint64_t immediate;
} ri;
struct {
struct
{
size_t reg1;
size_t reg2;
} rr;
struct
{
char *ptr;
size_t size;
} string;
} data;
} Instruction;

Expand All @@ -72,13 +83,31 @@ typedef struct

typedef struct
{
uint64_t *call_stack;
uint64_t *operands_stack;
uint8_t marked;
size_t size;
void *data;
} HeapObject;

typedef struct {
uint64_t *data;
size_t size;
size_t capacity;
} Array;

typedef struct {
HeapObject *data;
size_t size;
size_t capacity;
} PointersArray;

typedef struct
{
Array call_stack;
Array operands_stack;
PointersArray pointers_stack;
PointersArray objects;
uint64_t *locals;
size_t call_stack_size;
size_t call_stack_capacity;
size_t operands_stack_size;
size_t operands_stack_capacity;
size_t allocated_heap_size;
} VM;

Program init_program(void);
Expand Down
25 changes: 25 additions & 0 deletions src/assembler/assemble.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include "assembler/assembler.h"
#include "assembler/lexer.h"
#include "utils/memory.h"
Expand Down Expand Up @@ -167,6 +168,18 @@ read_literal_number()
return token;
}

static Token
read_literal_string()
{
Token token;
token = read_token();
if (token.type != TOKEN_STRING) {
fprintf(stderr, "Expected string, got %s\n", token.value);
exit(EXIT_FAILURE);
}
return token;
}

static void
read_ri(Instruction *instruction) {
Token token;
Expand Down Expand Up @@ -297,6 +310,18 @@ read_instruction(Instruction *instruction)
case TOKEN_PrintTopStackI64:
instruction->op = OP_PRINT_TOP_STACK_I64;
break;
case TOKEN_PushLiteralString:
instruction->op = OP_PUSH_LITERAL_STRING;
token = read_literal_string();
instruction->data.string.ptr = strdup(token.value);
instruction->data.string.size = strlen(token.value);
break;
case TOKEN_ConcatStrings:
instruction->op = OP_CONCAT_STRINGS;
break;
case TOKEN_PrintString:
instruction->op = OP_PRINT_STRING;
break;
case TOKEN_Exit:
instruction->op = OP_EXIT;
break;
Expand Down
9 changes: 9 additions & 0 deletions src/hal64.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,15 @@ instruction_as_string(Instruction instruction, char *string, size_t max_length)
case OP_PRINT_TOP_STACK_I64:
snprintf(string, max_length, "PRINT_TOP_STACK_I64");
break;
case OP_PUSH_LITERAL_STRING:
snprintf(string, max_length, "PUSH_LITERAL_STRING \"%s\"", instruction.data.string);
break;
case OP_CONCAT_STRINGS:
snprintf(string, max_length, "CONCAT_STRINGS");
break;
case OP_PRINT_STRING:
snprintf(string, max_length, "PRINT_STRING");
break;
default:
snprintf(string, max_length, "UNKNOWN");
break;
Expand Down
9 changes: 9 additions & 0 deletions src/lexer.l
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
%%

[ \t\n]+ { /* ignore whitespace */ }
\"([^\\"]|\\.)*\" { return TOKEN_STRING;}
[0-9]+ { return TOKEN_NUMBER; }
"---" { return TOKEN_HEADER_SEPARATOR; }
"globals" { return TOKEN_GLOBALS; }
Expand Down Expand Up @@ -46,6 +47,9 @@
"ModI64" { return TOKEN_ModI64; }
"Call" { return TOKEN_Call; }
"PrintTopStackI64" { return TOKEN_PrintTopStackI64; }
"PushLiteralString" { return TOKEN_PushLiteralString; }
"ConcatStrings" { return TOKEN_ConcatStrings; }
"PrintString" { return TOKEN_PrintString; }
"Exit" { return TOKEN_Exit; }

%%
Expand All @@ -70,6 +74,11 @@ Token read_token(void) {
token.value[0] = '\0';
return token;
}
if (token.type == TOKEN_STRING) {
strncpy(token.value, yytext + 1, yyleng - 2);
token.value[strlen(yytext) - 2] = '\0';
return token;
}
strcpy(token.value, yytext);
return token;
}
Loading

0 comments on commit d471a9e

Please sign in to comment.