mirror of
https://github.com/CPunch/Cosmo.git
synced 2024-11-05 08:10:05 +00:00
major main.c refactoring
- now takes command line arguments: Usage: ./bin/cosmo [-clsr] [args] available options are: -c <in> <out> compile <in> and dump to <out> -l <in> load dump from <in> -s <in...> compile and run <in...> script(s) -r start the repl
This commit is contained in:
parent
93a09698a9
commit
8c6ba18848
4
Makefile
4
Makefile
@ -1,8 +1,8 @@
|
||||
# make clean && make && ./bin/cosmo
|
||||
|
||||
CC=clang
|
||||
CFLAGS=-fPIE -Wall -O0 -Isrc -std=c99 -g
|
||||
LDFLAGS=-lm -fsanitize=address
|
||||
CFLAGS=-fPIE -Wall -O3 -Isrc -std=c99
|
||||
LDFLAGS=-lm #-fsanitize=address
|
||||
OUT=bin/cosmo
|
||||
|
||||
CHDR=\
|
||||
|
159
main.c
159
main.c
@ -1,21 +1,29 @@
|
||||
#include "cosmo.h"
|
||||
#include "cbaselib.h"
|
||||
#include "cchunk.h"
|
||||
#include "cdebug.h"
|
||||
#include "cvm.h"
|
||||
#include "cparse.h"
|
||||
#include "cbaselib.h"
|
||||
|
||||
#include "cdump.h"
|
||||
#include "cmem.h"
|
||||
#include "cosmo.h"
|
||||
#include "cparse.h"
|
||||
#include "cundump.h"
|
||||
#include "cvm.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
|
||||
static bool _ACTIVE = false;
|
||||
|
||||
int cosmoB_quitRepl(CState *state, int nargs, CValue *args) {
|
||||
int cosmoB_quitRepl(CState *state, int nargs, CValue *args)
|
||||
{
|
||||
_ACTIVE = false;
|
||||
|
||||
return 0; // we don't return anything
|
||||
}
|
||||
|
||||
int cosmoB_input(CState *state, int nargs, CValue *args) {
|
||||
int cosmoB_input(CState *state, int nargs, CValue *args)
|
||||
{
|
||||
// input() accepts the same params as print()!
|
||||
for (int i = 0; i < nargs; i++) {
|
||||
CObjString *str = cosmoV_toString(state, args[i]);
|
||||
@ -26,12 +34,14 @@ int cosmoB_input(CState *state, int nargs, CValue *args) {
|
||||
char line[1024];
|
||||
fgets(line, sizeof(line), stdin);
|
||||
|
||||
cosmoV_pushRef(state, (CObj*)cosmoO_copyString(state, line, strlen(line)-1)); // -1 for the \n
|
||||
cosmoV_pushRef(state,
|
||||
(CObj *)cosmoO_copyString(state, line, strlen(line) - 1)); // -1 for the \n
|
||||
|
||||
return 1; // 1 return value
|
||||
}
|
||||
|
||||
static bool interpret(CState *state, const char *script, const char *mod) {
|
||||
static bool interpret(CState *state, const char *script, const char *mod)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
// cosmoV_compileString pushes the result onto the stack (COBJ_ERROR or COBJ_CLOSURE)
|
||||
@ -50,15 +60,11 @@ static bool interpret(CState *state, const char *script, const char *mod) {
|
||||
return !ret;
|
||||
}
|
||||
|
||||
static void repl() {
|
||||
static void repl(CState *state)
|
||||
{
|
||||
char line[1024];
|
||||
_ACTIVE = true;
|
||||
|
||||
CState *state = cosmoV_newState();
|
||||
cosmoB_loadLibrary(state);
|
||||
cosmoB_loadOSLib(state);
|
||||
cosmoB_loadVM(state);
|
||||
|
||||
// add our custom REPL functions
|
||||
cosmoV_pushString(state, "quit");
|
||||
cosmoV_pushCFunction(state, cosmoB_quitRepl);
|
||||
@ -78,11 +84,10 @@ static void repl() {
|
||||
|
||||
interpret(state, line, "REPL");
|
||||
}
|
||||
|
||||
cosmoV_freeState(state);
|
||||
}
|
||||
|
||||
static char *readFile(const char* path) {
|
||||
static char *readFile(const char *path)
|
||||
{
|
||||
FILE *file = fopen(path, "rb");
|
||||
if (file == NULL) {
|
||||
fprintf(stderr, "Could not open file \"%s\".\n", path);
|
||||
@ -114,12 +119,10 @@ static char *readFile(const char* path) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static bool runFile(const char* fileName) {
|
||||
static bool runFile(CState *state, const char *fileName)
|
||||
{
|
||||
bool ret;
|
||||
char *script = readFile(fileName);
|
||||
CState *state = cosmoV_newState();
|
||||
cosmoB_loadLibrary(state);
|
||||
cosmoB_loadOSLib(state);
|
||||
|
||||
// add our input() function to the global table
|
||||
cosmoV_pushString(state, "input");
|
||||
@ -129,21 +132,119 @@ static bool runFile(const char* fileName) {
|
||||
|
||||
ret = interpret(state, script, fileName);
|
||||
|
||||
cosmoV_freeState(state);
|
||||
free(script);
|
||||
return ret; // let the caller know if the script failed
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
if (argc == 1) {
|
||||
repl();
|
||||
} else if (argc >= 2) { // they passed a file (or more lol)
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (!runFile(argv[i])) {
|
||||
int fileWriter(CState *state, const void *data, size_t size, const void *ud)
|
||||
{
|
||||
return !fwrite(data, size, 1, (FILE *)ud);
|
||||
}
|
||||
|
||||
int fileReader(CState *state, void *data, size_t size, const void *ud)
|
||||
{
|
||||
return fread(data, size, 1, (FILE *)ud) != 1;
|
||||
}
|
||||
|
||||
void compileScript(CState *state, const char *in, const char *out)
|
||||
{
|
||||
char *script = readFile(in);
|
||||
|
||||
FILE *fout = fopen(out, "wb");
|
||||
|
||||
if (cosmoV_compileString(state, script, in)) {
|
||||
CObjFunction *func = cosmoV_readClosure(*cosmoV_getTop(state, 0))->function;
|
||||
cosmoD_dump(state, func, fileWriter, (void *)fout);
|
||||
} else {
|
||||
cosmoV_pop(state); // pop the error off the stack
|
||||
cosmoV_printError(state, state->error);
|
||||
}
|
||||
|
||||
free(script);
|
||||
fclose(fout);
|
||||
|
||||
printf("[!] compiled %s to %s successfully!\n", in, out);
|
||||
}
|
||||
|
||||
void loadScript(CState *state, const char *in)
|
||||
{
|
||||
FILE *file;
|
||||
|
||||
file = fopen(in, "rb");
|
||||
if (!cosmoV_undump(state, fileReader, file)) {
|
||||
cosmoV_pop(state); // pop the error off the stack
|
||||
cosmoV_printError(state, state->error);
|
||||
return;
|
||||
};
|
||||
|
||||
printf("[!] loaded %s!\n", in);
|
||||
COSMOVMRESULT res = cosmoV_call(state, 0, 0); // 0 args being passed, 0 results expected
|
||||
|
||||
if (res == COSMOVM_RUNTIME_ERR)
|
||||
cosmoV_printError(state, state->error);
|
||||
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
void printUsage(const char *name)
|
||||
{
|
||||
printf("Usage: %s [-clsr] [args]\n\n", name);
|
||||
printf("available options are:\n"
|
||||
"-c <in> <out>\tcompile <in> and dump to <out>\n"
|
||||
"-l <in>\t\tload dump from <in>\n"
|
||||
"-s <in...>\t\tcompile and run <in...> script(s)\n"
|
||||
"-r\t\t\tstart the repl\n\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *const argv[])
|
||||
{
|
||||
CState *state = cosmoV_newState();
|
||||
cosmoB_loadLibrary(state);
|
||||
cosmoB_loadOSLib(state);
|
||||
cosmoB_loadVM(state);
|
||||
|
||||
int opt;
|
||||
bool isValid = false;
|
||||
while ((opt = getopt(argc, argv, "clsr")) != -1) {
|
||||
switch (opt) {
|
||||
case 'c':
|
||||
if (optind >= argc - 1) {
|
||||
printf("Usage: %s -c <in> <out>\n", argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
} else {
|
||||
compileScript(state, argv[optind], argv[optind + 1]);
|
||||
}
|
||||
isValid = true;
|
||||
break;
|
||||
case 'l':
|
||||
if (optind >= argc) {
|
||||
printf("Usage: %s -l <in>\n", argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
} else {
|
||||
loadScript(state, argv[optind]);
|
||||
}
|
||||
isValid = true;
|
||||
break;
|
||||
case 's':
|
||||
for (int i = optind; i < argc; i++) {
|
||||
if (!runFile(state, argv[i])) {
|
||||
printf("failed to run %s!\n", argv[i]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
isValid = true;
|
||||
break;
|
||||
case 'r':
|
||||
repl(state);
|
||||
isValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isValid) {
|
||||
printUsage(argv[0]);
|
||||
}
|
||||
|
||||
cosmoV_freeState(state);
|
||||
return 0;
|
||||
}
|
||||
|
@ -980,6 +980,4 @@ void cosmoB_loadVM(CState *state)
|
||||
|
||||
// register "vm" to the global table
|
||||
cosmoV_register(state, 1);
|
||||
|
||||
printf("[WARNING] the vm.* library has been loaded!\n");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user