Better cmdline args, start work on compiler
This commit is contained in:
29
src/compiler.c
Normal file
29
src/compiler.c
Normal file
@@ -0,0 +1,29 @@
|
||||
#include "compiler.h"
|
||||
#include "types.h"
|
||||
#include "include/estr.h"
|
||||
|
||||
char* compileGroundProgram(GroundProgram* program) {
|
||||
Estr start = CREATE_ESTR("global _start\nsection .text\n_start:\n");
|
||||
Estr data = CREATE_ESTR("section .rodata\n");
|
||||
|
||||
for (size_t i = 0; i < program->size; i++) {
|
||||
switch (program->instructions[i].type) {
|
||||
case END: {
|
||||
APPEND_ESTR(start, " mov rax, 60\n");
|
||||
APPEND_ESTR(start, " mov rdi, 0\n");
|
||||
APPEND_ESTR(start, " syscall\n");
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
printf("no\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Estr complete = CREATE_ESTR("");
|
||||
APPEND_ESTR(complete, start.str);
|
||||
APPEND_ESTR(complete, data.str)
|
||||
|
||||
return complete.str;
|
||||
}
|
||||
3
src/compiler.h
Normal file
3
src/compiler.h
Normal file
@@ -0,0 +1,3 @@
|
||||
#include "types.h"
|
||||
|
||||
char* compileGroundProgram(GroundProgram* program);
|
||||
52
src/include/estr.h
Normal file
52
src/include/estr.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef ESTR_H
|
||||
#define ESTR_H
|
||||
|
||||
/*
|
||||
|
||||
estr.h - Easy string manipulation
|
||||
This library has macros to allow easier manipulation of strings. No longer shall
|
||||
you have to malloc and realloc away to keep adding to your strings.
|
||||
|
||||
Usage:
|
||||
|
||||
Estr myString = CREATE_ESTR("my awesome string");
|
||||
APPEND_ESTR(myString, " is so cool");
|
||||
printf("%s\n", myString.str);
|
||||
|
||||
*/
|
||||
|
||||
#define CREATE_ESTR(instr) \
|
||||
(Estr) { \
|
||||
.str = instr,\
|
||||
.size = strlen(instr),\
|
||||
.shouldBeFreed = 0, \
|
||||
.destroyed = 0 \
|
||||
}
|
||||
|
||||
#define APPEND_ESTR(estr, instr) { \
|
||||
estr.size = estr.size + strlen(instr); \
|
||||
char* tmp_ptr = malloc(estr.size + 1); \
|
||||
if (tmp_ptr == NULL) printf("WARNING: Could not realloc estr " #estr "\n"); \
|
||||
else { \
|
||||
snprintf(tmp_ptr, estr.size + 1, "%s%s", estr.str, instr); \
|
||||
if (estr.shouldBeFreed > 0) free(estr.str); \
|
||||
estr.shouldBeFreed = 1; \
|
||||
estr.str = tmp_ptr; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define DESTROY_ESTR(estr) if (estr.shouldBeFreed > 0 && estr.destroyed < 1) free(estr.str);
|
||||
|
||||
typedef struct Estr {
|
||||
char* str;
|
||||
size_t size;
|
||||
int8_t shouldBeFreed;
|
||||
int8_t destroyed;
|
||||
} Estr;
|
||||
|
||||
#endif // ESTR_H
|
||||
@@ -352,7 +352,7 @@ GroundStruct parseStruct(GroundProgram* in, GroundScope* scope, size_t errorOffs
|
||||
|
||||
GroundValue gv;
|
||||
|
||||
switch (stringToValueType(in->instructions[i].args.args[0].value.refName)) {
|
||||
switch (stringToValueType(in->instructions[i].args.args[1].value.refName)) {
|
||||
case INT: {
|
||||
gv = createIntGroundValue(0);
|
||||
break;
|
||||
|
||||
46
src/main.c
46
src/main.c
@@ -1,5 +1,6 @@
|
||||
#include "parser.h"
|
||||
#include "interpreter.h"
|
||||
#include "compiler.h"
|
||||
#include <stdio.h>
|
||||
|
||||
char* getFileContents(const char* filename) {
|
||||
@@ -39,6 +40,7 @@ char* getFileContents(const char* filename) {
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
/*
|
||||
if (argc < 2) {
|
||||
printf("Usage: ground [file]\n");
|
||||
exit(1);
|
||||
@@ -46,5 +48,49 @@ int main(int argc, char** argv) {
|
||||
char* file = getFileContents(argv[1]);
|
||||
GroundProgram program = parseFile(file);
|
||||
free(file);
|
||||
char* compiled = compileGroundProgram(&program);
|
||||
printf("%s\n", compiled);
|
||||
interpretGroundProgram(&program, NULL);
|
||||
*/
|
||||
|
||||
if (argc < 2) {
|
||||
printf("Usage: %s <file> [-c] [--compile] [-h] [--help]\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
bool compile = false;
|
||||
char* fileName = NULL;
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp("--compile", argv[i]) == 0 || strcmp("-c", argv[i]) == 0) {
|
||||
compile = true;
|
||||
}
|
||||
else if (strcmp("--help", argv[i]) == 0 || strcmp("-h", argv[i]) == 0) {
|
||||
printf("GroundVM help\n");
|
||||
printf("Usage: %s <file> [-c] [--compile] [-h] [--help]\n", argv[0]);
|
||||
printf("Options:\n");
|
||||
printf(" -c or --compile: Outputs Linux x86_64 assembly instead of interpreting (WIP)\n");
|
||||
printf(" -h or --help: Shows this help message\n");
|
||||
exit(0);
|
||||
} else {
|
||||
fileName = argv[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (fileName == NULL) {
|
||||
printf("Usage: %s <file> [-c] [--compile] [-h] [--help]\n", argv[0]);
|
||||
printf("Error: No file name provided\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char* file = getFileContents(fileName);
|
||||
GroundProgram program = parseFile(file);
|
||||
free(file);
|
||||
|
||||
if (compile) {
|
||||
char* compiled = compileGroundProgram(&program);
|
||||
printf("%s\n", compiled);
|
||||
} else {
|
||||
interpretGroundProgram(&program, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user