3 Commits

10 changed files with 84 additions and 12 deletions

File diff suppressed because one or more lines are too long

View File

@@ -3,6 +3,7 @@
#include "compiler.h" #include "compiler.h"
#include "types.h" #include "types.h"
#include "serialize.h" #include "serialize.h"
#include "repl.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@@ -43,9 +44,8 @@ char* getFileContents(const char* filename) {
} }
int main(int argc, char** argv) { int main(int argc, char** argv) {
if (argc < 2) { if (argc == 1) {
printf("Usage: %s <file> [-c] [--compile] [-h] [--help]\n", argv[0]); exit(repl());
exit(1);
} }
bool compile = false; bool compile = false;
@@ -71,7 +71,7 @@ int main(int argc, char** argv) {
printf(" -w <output> or --writebytecode <output>: Outputs binary Ground bytecode"); printf(" -w <output> or --writebytecode <output>: Outputs binary Ground bytecode");
printf(" -b <output> or --bytecode <output>: Inputs binary Ground bytecode"); printf(" -b <output> or --bytecode <output>: Inputs binary Ground bytecode");
exit(0); exit(0);
} else if (strcmp("--writebytecode", argv[i]) == 0 || strcmp("-w", argv[i]) == 0) { } else if (strcmp("--writeBytecode", argv[i]) == 0 || strcmp("-w", argv[i]) == 0) {
if (compile) { if (compile) {
printf("Cannot choose both bytecode and compilation"); printf("Cannot choose both bytecode and compilation");
exit(1); exit(1);

View File

@@ -194,6 +194,7 @@ static GroundInstType getInstructionType(const char* inst) {
if (strcmp(inst, "use") == 0) return USE; if (strcmp(inst, "use") == 0) return USE;
if (strcmp(inst, "extern") == 0) return EXTERN; if (strcmp(inst, "extern") == 0) return EXTERN;
if (strcmp(inst, "drop") == 0) return DROP; if (strcmp(inst, "drop") == 0) return DROP;
if (strcmp(inst, "license") == 0) return LICENSE;
if (strcmp(inst, "PAUSE") == 0) return PAUSE; if (strcmp(inst, "PAUSE") == 0) return PAUSE;
fprintf(stderr, "Error: Unknown instruction: %s\n", inst); fprintf(stderr, "Error: Unknown instruction: %s\n", inst);

58
src/repl.c Normal file
View File

@@ -0,0 +1,58 @@
/*
* Ground REPL (when ground is ran without any arguments)
* Copyright (C) 2026 DiamondNether90
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "interpreter.h"
#include "include/estr.h"
#include "parser.h"
#define BUFFER_SIZE 1024
int repl() {
printf("Ground REPL\n");
printf("Copyright (C) DiamondNether90 2026\n");
printf("Distributed under the GNU GPL-3.0 license; type \"license\" for more info\n");
char input[BUFFER_SIZE];
GroundVariable* variables = NULL;
GroundLabel* labels = NULL;
GroundScope scope;
scope.variables = &variables;
scope.labels = &labels;
scope.isMainScope = true;
while (true) {
Estr programString = CREATE_ESTR("");
// Get program
printf(">>> ");
while (true) {
fgets(input, BUFFER_SIZE, stdin);
if (strcmp(input, "\n") == 0) {
break;
}
APPEND_ESTR(programString, input);
printf("...");
}
// Interpret program
GroundProgram program = createGroundProgram();
program = parseFile(programString.str);
interpretGroundProgram(&program, &scope);
DESTROY_ESTR(programString);
}
}

1
src/repl.h Normal file
View File

@@ -0,0 +1 @@
int repl();

View File

@@ -87,11 +87,14 @@ GroundValue copyGroundValue(const GroundValue* gv) {
case CHAR: newGv.data.charVal = gv->data.charVal; break; case CHAR: newGv.data.charVal = gv->data.charVal; break;
case BOOL: newGv.data.boolVal = gv->data.boolVal; break; case BOOL: newGv.data.boolVal = gv->data.boolVal; break;
case STRING: case STRING:
/*
if (gv->data.stringVal != NULL) { if (gv->data.stringVal != NULL) {
newGv.data.stringVal = strdup(gv->data.stringVal); newGv.data.stringVal = strdup(gv->data.stringVal);
} else { } else {
newGv.data.stringVal = NULL; newGv.data.stringVal = NULL;
} }
*/
newGv.data.stringVal = gv->data.stringVal;
break; break;
case LIST: { case LIST: {
List newList = createList(); List newList = createList();
@@ -258,7 +261,8 @@ void printGroundValue(GroundValue* gv) {
void freeGroundValue(GroundValue* gv) { void freeGroundValue(GroundValue* gv) {
if (gv->type == STRING && gv->data.stringVal != NULL) { if (gv->type == STRING && gv->data.stringVal != NULL) {
free(gv->data.stringVal); // leak some memory for now
// free(gv->data.stringVal);
gv->data.stringVal = NULL; gv->data.stringVal = NULL;
} }
if (gv->type == LIST && gv->data.listVal.values != NULL) { if (gv->type == LIST && gv->data.listVal.values != NULL) {

View File

@@ -29,7 +29,7 @@ void wasm_print(const char* str);
#endif #endif
typedef enum GroundInstType { typedef enum GroundInstType {
IF, JUMP, END, INPUT, PRINT, PRINTLN, SET, GETTYPE, EXISTS, SETLIST, SETLISTAT, GETLISTAT, GETLISTSIZE, LISTAPPEND, GETSTRSIZE, GETSTRCHARAT, ADD, SUBTRACT, MULTIPLY, DIVIDE, EQUAL, INEQUAL, NOT, GREATER, LESSER, STOI, STOD, ITOC, CTOI, TOSTRING, FUN, RETURN, ENDFUN, PUSHARG, CALL, STRUCT, ENDSTRUCT, INIT, GETFIELD, SETFIELD, USE, EXTERN, CREATELABEL, PAUSE, DROP, ERRORCMD IF, JUMP, END, INPUT, PRINT, PRINTLN, SET, GETTYPE, EXISTS, SETLIST, SETLISTAT, GETLISTAT, GETLISTSIZE, LISTAPPEND, GETSTRSIZE, GETSTRCHARAT, ADD, SUBTRACT, MULTIPLY, DIVIDE, EQUAL, INEQUAL, NOT, GREATER, LESSER, STOI, STOD, ITOC, CTOI, TOSTRING, FUN, RETURN, ENDFUN, PUSHARG, CALL, STRUCT, ENDSTRUCT, INIT, GETFIELD, SETFIELD, USE, EXTERN, CREATELABEL, PAUSE, DROP, LICENSE, ERRORCMD
} GroundInstType; } GroundInstType;
typedef enum GroundValueType { typedef enum GroundValueType {

View File

@@ -1,5 +0,0 @@
[hello, there, general, kenobi][hello, there, general, kenobi][hello, there, general, hello]
hello
there
general
Nqb˜V

2
tests/pause.grnd Normal file
View File

@@ -0,0 +1,2 @@
set &x 5
PAUSE

View File

@@ -15,7 +15,7 @@ for f in *.grnd; do
ground "$f" > log.txt ground "$f" > log.txt
FILE="log.txt" FILE="log.txt"
FAILED="\033[31mFailed:\n\033[0m" FAILED="\033[31mFailed\n\033[0m"
if [[ "$f" == "closure.grnd" ]]; then if [[ "$f" == "closure.grnd" ]]; then
if !(cmp -s "$FILE" <(printf "13 10\n")); if !(cmp -s "$FILE" <(printf "13 10\n"));
then printf $FAILED then printf $FAILED
@@ -76,5 +76,6 @@ for f in *.grnd; do
exit 1 exit 1
fi fi
done done
rm log.txt
printf "\033[32mAll tests passed!\n\033[0m" printf "\033[32mAll tests passed!\n\033[0m"
exit 0 exit 0