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;
|
GroundValue gv;
|
||||||
|
|
||||||
switch (stringToValueType(in->instructions[i].args.args[0].value.refName)) {
|
switch (stringToValueType(in->instructions[i].args.args[1].value.refName)) {
|
||||||
case INT: {
|
case INT: {
|
||||||
gv = createIntGroundValue(0);
|
gv = createIntGroundValue(0);
|
||||||
break;
|
break;
|
||||||
|
|||||||
46
src/main.c
46
src/main.c
@@ -1,5 +1,6 @@
|
|||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "interpreter.h"
|
#include "interpreter.h"
|
||||||
|
#include "compiler.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
char* getFileContents(const char* filename) {
|
char* getFileContents(const char* filename) {
|
||||||
@@ -39,6 +40,7 @@ char* getFileContents(const char* filename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
/*
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
printf("Usage: ground [file]\n");
|
printf("Usage: ground [file]\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -46,5 +48,49 @@ int main(int argc, char** argv) {
|
|||||||
char* file = getFileContents(argv[1]);
|
char* file = getFileContents(argv[1]);
|
||||||
GroundProgram program = parseFile(file);
|
GroundProgram program = parseFile(file);
|
||||||
free(file);
|
free(file);
|
||||||
|
char* compiled = compileGroundProgram(&program);
|
||||||
|
printf("%s\n", compiled);
|
||||||
interpretGroundProgram(&program, NULL);
|
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