Add string operations

This commit is contained in:
2025-12-01 12:28:15 +11:00
parent 995c1d984b
commit 6d782d65b7
4 changed files with 65 additions and 6 deletions

View File

@@ -25,13 +25,13 @@ Progress marker:
- [x] Labels - [x] Labels
- [x] Console I/O - [x] Console I/O
- [x] Control flow - [x] Control flow
- [ ] Data - [x] Data
- [x] Variable creation - [x] Variable creation
- [x] Variable access - [x] Variable access
- [ ] Lists - [x] Lists
- [ ] Creation - [x] Creation
- [ ] Access - [x] Access
- [ ] String operations - [x] String operations
- [x] Maths - [x] Maths
- [x] Comparisions - [x] Comparisions
- [ ] Type conversions - [ ] Type conversions

View File

@@ -697,6 +697,54 @@ void interpretGroundInstruction(GroundInstruction inst, GroundScope* scope) {
break; break;
} }
/*
* STRING OPERATIONS
* Allows easier manipulation of strings.
* Instructions:
* getstrcharat, getstrsize
*/
case GETSTRCHARAT: {
if (in->args.length < 3) {
runtimeError(TOO_FEW_ARGS, "Expecting 3 args", in, currentInstruction);
}
if (in->args.length > 3) {
runtimeError(TOO_MANY_ARGS, "Expecting 3 args", in, currentInstruction);
}
if (in->args.args[0].type != VALUE && in->args.args[0].value.value.type != STRING) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a String for arg 1", in, currentInstruction);
}
if (in->args.args[1].type != VALUE && in->args.args[1].value.value.type != INT) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting an Int for arg 2", in, currentInstruction);
}
if (in->args.args[2].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef for arg 3", in, currentInstruction);
}
char* str = in->args.args[0].value.value.data.stringVal;
int64_t idx = in->args.args[1].value.value.data.intVal;
if (idx < strlen(str)) {
addVariable(scope->variables, in->args.args[2].value.refName, createCharGroundValue(str[idx]));
} else {
runtimeError(STRING_ERROR, "Out of bounds index", in, currentInstruction);
}
break;
}
case GETSTRSIZE: {
if (in->args.length < 2) {
runtimeError(TOO_FEW_ARGS, "Expecting 2 args", in, currentInstruction);
}
if (in->args.length > 2) {
runtimeError(TOO_MANY_ARGS, "Expecting 2 args", in, currentInstruction);
}
if (in->args.args[0].type != VALUE && in->args.args[0].value.value.type != STRING) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a String for arg 1", in, currentInstruction);
}
if (in->args.args[1].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef for arg 2", in, currentInstruction);
}
addVariable(scope->variables, in->args.args[1].value.refName, createIntGroundValue(strlen(in->args.args[0].value.value.data.stringVal)));
break;
}
/* /*
* COMPARISONS * COMPARISONS
* Allows comparing values. * Allows comparing values.

View File

@@ -7,7 +7,7 @@
#include "include/uthash.h" #include "include/uthash.h"
typedef enum GroundRuntimeError { typedef enum GroundRuntimeError {
ARG_TYPE_MISMATCH, TOO_FEW_ARGS, TOO_MANY_ARGS, UNKNOWN_LABEL, UNKNOWN_VARIABLE, LIST_ERROR, FIXME ARG_TYPE_MISMATCH, TOO_FEW_ARGS, TOO_MANY_ARGS, UNKNOWN_LABEL, UNKNOWN_VARIABLE, LIST_ERROR, STRING_ERROR, FIXME
} GroundRuntimeError; } GroundRuntimeError;
typedef struct GroundLabel { typedef struct GroundLabel {

11
tests/string.grnd Normal file
View File

@@ -0,0 +1,11 @@
input &str
getstrsize $str &size
set &idx 0
@loop
getstrcharat $str $idx &char
println $char
add 1 $idx &idx
equal $idx $size &cond
if $cond %loopend
jump %loop
@loopend