Fix type safety issue
This commit is contained in:
16
Makefile
16
Makefile
@@ -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:
|
||||||
|
|||||||
12
README.md
12
README.md
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
3
tests/uhoh.grnd
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
fun !dingle -int -function &in
|
||||||
|
call !in &tmp
|
||||||
|
endfun
|
||||||
Reference in New Issue
Block a user