Fix type safety issue

This commit is contained in:
2025-12-11 13:07:37 +11:00
parent 2ca3789024
commit 4c6aa97fd5
5 changed files with 54 additions and 10 deletions

View File

@@ -1,7 +1,11 @@
CC = gcc CC = gcc
CFLAGS = -Wall -Wextra -O3 -Isrc/include -Iinclude CFLAGS = -Wall -Wextra -Isrc/include -Iinclude
LDFLAGS = LDFLAGS =
# Install paths
PREFIX ?= /usr/local
DESTDIR ?=
# Directories # Directories
SRC_DIR = src SRC_DIR = src
BUILD_DIR = build BUILD_DIR = build
@@ -68,6 +72,16 @@ $(BUILD_DIR) $(BIN_DIR) $(LIB_DIR) $(INC_DIR) $(OBJ_DIR):
clean: clean:
rm -rf $(BUILD_DIR) rm -rf $(BUILD_DIR)
# Install executable, library, and header
.PHONY: install
install: both
mkdir -p $(DESTDIR)$(PREFIX)/bin
mkdir -p $(DESTDIR)$(PREFIX)/lib
mkdir -p $(DESTDIR)$(PREFIX)/include
cp $(EXECUTABLE) $(DESTDIR)$(PREFIX)/bin/
cp $(SHARED_LIB) $(DESTDIR)$(PREFIX)/lib/
cp $(HEADER) $(DESTDIR)$(PREFIX)/include/
# Debug: print variables # Debug: print variables
.PHONY: debug .PHONY: debug
debug: debug:

View File

@@ -85,4 +85,16 @@ build
- [ ] Custom data structures - [ ] Custom data structures
- [ ] Working with external libraries - [ ] Working with external libraries
## Debugger
Ground now has an inbuilt debugger. To access this debugger, insert the `PAUSE` instruction (no arguments required) into the program. This should bring you to an interactive prompt.
Commands:
* continue: Continues execution of the program
* exit: Stops execution of the program early
* dump: Shows all variables and their contents
* inspect (variable): Shows the contents of a variable
* eval (code): Runs Ground code in the current scope
* help: Shows a help message

View File

@@ -244,6 +244,7 @@ GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a TypeRef for arg 2", &in->instructions[i], i); runtimeError(ARG_TYPE_MISMATCH, "Expecting a TypeRef for arg 2", &in->instructions[i], i);
} }
GroundArg* args = in->instructions[i].args.args; GroundArg* args = in->instructions[i].args.args;
function->returnType = stringToValueType(args[1].value.refName);
size_t length = in->instructions[i].args.length; size_t length = in->instructions[i].args.length;
for (size_t j = 2; j < length; j += 2) { for (size_t j = 2; j < length; j += 2) {
if (args[j].type != TYPEREF) { if (args[j].type != TYPEREF) {
@@ -591,6 +592,9 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
addVariable(scope->variables, in->args.args[1].value.refName, createStringGroundValue("custom")); addVariable(scope->variables, in->args.args[1].value.refName, createStringGroundValue("custom"));
break; break;
} }
case FUNCTION: {
addVariable(scope->variables, in->args.args[1].value.refName, createStringGroundValue("function"));
}
case NONE: { case NONE: {
addVariable(scope->variables, in->args.args[1].value.refName, createStringGroundValue("none")); addVariable(scope->variables, in->args.args[1].value.refName, createStringGroundValue("none"));
} }
@@ -617,7 +621,6 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
} else { } else {
addVariable(scope->variables, in->args.args[1].value.refName, createBoolGroundValue(false)); addVariable(scope->variables, in->args.args[1].value.refName, createBoolGroundValue(false));
} }
break; break;
} }
case SETLIST: { case SETLIST: {
@@ -1318,16 +1321,13 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
} }
case CALL: { case CALL: {
if (in->args.length < 2) { if (in->args.length < 2) {
runtimeError(TOO_FEW_ARGS, "Expecting 2 args", in, currentInstruction); runtimeError(TOO_FEW_ARGS, "Expecting 2 or more args", in, currentInstruction);
}
if (in->args.length > 2) {
runtimeError(TOO_MANY_ARGS, "Expecting 2 args", in, currentInstruction);
} }
if (in->args.args[0].type != FNREF) { if (in->args.args[0].type != FNREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a FunctionRef for arg 1", in, currentInstruction); runtimeError(ARG_TYPE_MISMATCH, "Expecting a FunctionRef for arg 1", in, currentInstruction);
} }
if (in->args.args[1].type != DIRREF) { if (in->args.args[in->args.length - 1].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef for arg 2", in, currentInstruction); runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef as the last arg", in, currentInstruction);
} }
GroundVariable* variables = NULL; GroundVariable* variables = NULL;
GroundLabel* labels = NULL; GroundLabel* labels = NULL;
@@ -1343,13 +1343,28 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
runtimeError(UNKNOWN_VARIABLE, "Provided reference does not reference a function", in, currentInstruction); runtimeError(UNKNOWN_VARIABLE, "Provided reference does not reference a function", in, currentInstruction);
} }
GroundFunction* function = value->data.fnVal; GroundFunction* function = value->data.fnVal;
if (function->argSize < in->args.length - 2) {
runtimeError(TOO_FEW_ARGS, "Incorrect amount of arguments provided for function", in, currentInstruction);
}
if (function->argSize > in->args.length - 2) {
runtimeError(TOO_MANY_ARGS, "Incorrect amount of arguments provided for function", in, currentInstruction);
}
for (size_t i = 0; i < function->argSize; i++) {
if (in->args.args[i + 1].type != VALUE) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a Value", in, currentInstruction);
}
if (in->args.args[i + 1].value.value.type != function->args[i].type) {
runtimeError(ARG_TYPE_MISMATCH, "Mismatched function argument types", in, currentInstruction);
}
addVariable(newScope.variables, function->args[i].name, in->args.args[i + 1].value.value);
}
size_t currentCurrentInstruction = currentInstruction; size_t currentCurrentInstruction = currentInstruction;
currentInstruction = function->startLine; currentInstruction = function->startLine;
GroundValue returnValue = interpretGroundProgram(&function->program, &newScope); GroundValue returnValue = interpretGroundProgram(&function->program, &newScope);
if (returnValue.type != function->returnType) { if (returnValue.type != function->returnType) {
runtimeError(RETURN_TYPE_MISMATCH, "Unexpected return value type from function", in, currentInstruction); runtimeError(RETURN_TYPE_MISMATCH, "Unexpected return value type from function", in, currentInstruction);
} }
addVariable(scope->variables, in->args.args[1].value.refName, returnValue); addVariable(scope->variables, in->args.args[in->args.length - 1].value.refName, returnValue);
currentInstruction = currentCurrentInstruction; currentInstruction = currentCurrentInstruction;
break; break;
} }

View File

@@ -1,5 +1,5 @@
fun !dingus -string fun !dingus -string
return "dingus" return "dingle"
endfun endfun
call !dingus &e call !dingus &e

3
tests/uhoh.grnd Normal file
View File

@@ -0,0 +1,3 @@
fun !dingle -int -function &in
call !in &tmp
endfun