forked from ground/ground
More stuff
This commit is contained in:
@@ -134,7 +134,7 @@ Appends an item to a list.
|
||||
|
||||
Usage: `listappend *list $var`
|
||||
|
||||
### String Operations (ALL WORK IN PROGRESS)
|
||||
### String Operations
|
||||
|
||||
#### getstrsize
|
||||
|
||||
@@ -200,7 +200,7 @@ Checks if the left value is lesser than the right value. Outputs a boolean to a
|
||||
|
||||
Usage: `lesser $value $value &var`
|
||||
|
||||
### Type Conversions
|
||||
### Type Conversions (ALL WORK IN PROGRESS)
|
||||
|
||||
#### stoi
|
||||
|
||||
@@ -248,6 +248,24 @@ Usage: `pusharg $value`
|
||||
|
||||
#### call
|
||||
|
||||
Calls a function, with all the arguments in the argument list.
|
||||
Calls a function, with all the arguments in the argument list. The return value will be put in the specified variable.
|
||||
|
||||
Usage: `call !function`
|
||||
Usage: `call !function &var
|
||||
|
||||
### Interacting with Libraries (ALL WORK IN PROGRESS)
|
||||
|
||||
#### use
|
||||
|
||||
Attempts to import another Ground program. Gets inserted wherever the use statement is. Any code (including code outside function declarations) will be executed.
|
||||
|
||||
Note: Ground will check the directory where the program is stored when trying to find imported programs. If that fails, it will check the directory set in the $GROUND_PATH environment variable set by your system. The '.grnd' extension is appended automatically.
|
||||
|
||||
Usage: `use $stringvalue`
|
||||
|
||||
#### extern
|
||||
|
||||
Attempts to import a shared object library written for Ground. All functions in the external library will be usable with `call`.
|
||||
|
||||
Note: Ground will check the directory where the program is stored when trying to find external programs. If that fails, it will check the directory set in the $GROUND_PATH environment variable set by your system. The '.so', '.dll', etc extension is appended automatically.
|
||||
|
||||
Usage: `extern $stringvalue`
|
97
src/main.cpp
97
src/main.cpp
@@ -54,7 +54,10 @@ enum class Instructions {
|
||||
Add, Subtract, Multiply, Divide,
|
||||
Equal, Inequal, Greater, Lesser,
|
||||
End, Set, Empty,
|
||||
Setlist, Getlistat, Setlistat, Getlistsize, Listappend, Listprepend
|
||||
Setlist, Getlistat, Setlistat, Getlistsize, Listappend, Listprepend,
|
||||
Getstrcharat, Getstrsize,
|
||||
Stoi, Stod, tostring,
|
||||
Fun, Endfun, Pusharg, Call
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -531,6 +534,55 @@ void exec(vector<Instruction> in) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
/*
|
||||
getstrcharat instruction
|
||||
This instruction gets a character from a string at an index and saves it
|
||||
to a variable.
|
||||
*/
|
||||
case Instructions::Getstrcharat:
|
||||
if (l.args.size() < 3) {
|
||||
error("Could not find all arguments required for Getstrcharat inbuilt");
|
||||
}
|
||||
{
|
||||
string instr;
|
||||
int ref;
|
||||
Direct var;
|
||||
|
||||
if (holds_alternative<Literal>(l.args[0])) {
|
||||
if (holds_alternative<string>(get<Literal>(l.args[0]).val)) {
|
||||
instr = get<string>(get<Literal>(l.args[0]).val);
|
||||
} else {
|
||||
error("First argument of getlistat must be a string literal");
|
||||
}
|
||||
} else {
|
||||
error("First argument of getlistat must be a string literal");
|
||||
}
|
||||
|
||||
if (holds_alternative<Literal>(l.args[1])) {
|
||||
if (holds_alternative<int>(get<Literal>(l.args[1]).val)) {
|
||||
ref = get<int>(get<Literal>(l.args[1]).val);
|
||||
} else {
|
||||
error("Second argument of getlistat must be an integer literal");
|
||||
}
|
||||
} else {
|
||||
error("Second argument of getlistat must be an integer literal");
|
||||
}
|
||||
|
||||
if (holds_alternative<Direct>(l.args[2])) {
|
||||
var = get<Direct>(l.args[2]);
|
||||
} else {
|
||||
error("Third argument of getlistat must be a direct reference");
|
||||
}
|
||||
|
||||
if (instr.size() > ref) {
|
||||
Literal newLit;
|
||||
newLit.val = instr[ref];
|
||||
variables[var.varName] = newLit;
|
||||
} else {
|
||||
error("Index " + to_string(ref) + " out of range of string " + instr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
/*
|
||||
setlistat instruction
|
||||
This instruction sets an item in a list to be a certain value.
|
||||
@@ -643,6 +695,40 @@ void exec(vector<Instruction> in) {
|
||||
break;
|
||||
}
|
||||
/*
|
||||
getstrsize instruction
|
||||
This instruction saves the size of a string in a variable.
|
||||
*/
|
||||
case Instructions::Getstrsize:
|
||||
if (l.args.size() < 2) {
|
||||
error("Could not find all arguments required for Getstrsize inbuilt");
|
||||
}
|
||||
{
|
||||
string ref;
|
||||
Direct var;
|
||||
|
||||
if (holds_alternative<Literal>(l.args[0])) {
|
||||
if (holds_alternative<string>(get<Literal>(l.args[0]).val)) {
|
||||
ref = get<string>(get<Literal>(l.args[0]).val);
|
||||
} else {
|
||||
error("First argument of getlistsize must be a string value");
|
||||
}
|
||||
} else {
|
||||
error("First argument of getlistsize must be a string value");
|
||||
}
|
||||
|
||||
if (holds_alternative<Direct>(l.args[1])) {
|
||||
var = get<Direct>(l.args[1]);
|
||||
} else {
|
||||
error("Second argument of getlistsize must be a direct reference");
|
||||
}
|
||||
|
||||
Literal newLit;
|
||||
newLit.val = int(ref.size());
|
||||
variables[var.varName] = newLit;
|
||||
|
||||
break;
|
||||
}
|
||||
/*
|
||||
stdin instruction
|
||||
This instruction takes input from the standard character input via
|
||||
the C++ getline() function, and saves it to a variable.
|
||||
@@ -705,6 +791,12 @@ void exec(vector<Instruction> in) {
|
||||
final.val = get<double>(left.val) + double(get<int>(right.val));
|
||||
} else if (holds_alternative<string>(left.val) && holds_alternative<string>(right.val)) {
|
||||
final.val = get<string>(left.val) + get<string>(right.val);
|
||||
} else if (holds_alternative<string>(left.val) && holds_alternative<char>(right.val)) {
|
||||
final.val = get<string>(left.val).append(&get<char>(right.val));
|
||||
} else if (holds_alternative<char>(left.val) && holds_alternative<string>(right.val)) {
|
||||
final.val = string().append(&get<char>(left.val)) + get<string>(right.val);
|
||||
} else if (holds_alternative<char>(left.val) && holds_alternative<char>(right.val)) {
|
||||
final.val = string().append(&get<char>(left.val)).append(&get<char>(right.val));
|
||||
} else {
|
||||
error("Cannot add those two values");
|
||||
}
|
||||
@@ -1267,6 +1359,9 @@ vector<Instruction> parser(vector<vector<string>> in) {
|
||||
else if (i == "setlistat") newInst.inst = Instructions::Setlistat;
|
||||
else if (i == "getlistat") newInst.inst = Instructions::Getlistat;
|
||||
else if (i == "getlistsize") newInst.inst = Instructions::Getlistsize;
|
||||
else if (i == "listappend") newInst.inst = Instructions::Listappend;
|
||||
else if (i == "getstrsize") newInst.inst = Instructions::Getstrsize;
|
||||
else if (i == "getstrcharat") newInst.inst = Instructions::Getstrcharat;
|
||||
else error("Unexpected token: " + i);
|
||||
} else {
|
||||
Types type = getType(i);
|
||||
|
89
tests/everything.grnd
Normal file
89
tests/everything.grnd
Normal file
@@ -0,0 +1,89 @@
|
||||
# I/O
|
||||
|
||||
stdlnout "Hello there!"
|
||||
stdout "What is your name? "
|
||||
stdin &name
|
||||
add "Hello, " $name &out
|
||||
stdlnout $out
|
||||
|
||||
# Types
|
||||
stdlnout "dingus"
|
||||
stdlnout 7
|
||||
stdlnout 3.14159
|
||||
stdlnout true
|
||||
stdlnout 'e'
|
||||
|
||||
# Variables
|
||||
|
||||
set &testVar "This is a test"
|
||||
stdlnout $testVar
|
||||
|
||||
# Lists
|
||||
|
||||
setlist *testList "Item 1" "Another Item" "Item the Third"
|
||||
getlistat *testList 2 &tmp
|
||||
stdlnout $tmp
|
||||
|
||||
setlistat *testList 1 "I changed this item"
|
||||
getlistat *testList 1 &tmp
|
||||
stdlnout $tmp
|
||||
|
||||
listappend *testList "I appended this item"
|
||||
getlistat *testList 3 &tmp
|
||||
stdlnout $tmp
|
||||
|
||||
getlistsize *testList &tmp
|
||||
stdlnout $tmp
|
||||
|
||||
# String Operations
|
||||
|
||||
set &testStr "dingus"
|
||||
|
||||
getstrsize $testStr &tmp
|
||||
stdlnout $tmp
|
||||
|
||||
getstrcharat $testStr 3 &tmp
|
||||
stdlnout $tmp
|
||||
|
||||
# Maths
|
||||
|
||||
add 1 1 &tmp
|
||||
stdlnout $tmp
|
||||
|
||||
subtract 10 5 &tmp
|
||||
stdlnout $tmp
|
||||
|
||||
multiply 15 15 &tmp
|
||||
stdlnout $tmp
|
||||
|
||||
divide 36 4 &tmp
|
||||
stdlnout $tmp
|
||||
|
||||
# Comparisons
|
||||
|
||||
equal 5 5 &tmp
|
||||
stdlnout $tmp
|
||||
|
||||
inequal 5 5 &tmp
|
||||
stdlnout $tmp
|
||||
|
||||
greater 10 5 &tmp
|
||||
stdlnout $tmp
|
||||
|
||||
lesser 10 5 &tmp
|
||||
stdlnout $tmp
|
||||
|
||||
# Control flow
|
||||
|
||||
set &counter 0
|
||||
|
||||
@myLabel
|
||||
add $counter 1 &counter
|
||||
stdlnout $counter
|
||||
inequal $counter 10 &case
|
||||
if $case %myLabel
|
||||
|
||||
# That's it!
|
||||
|
||||
stdlnout "Everything ran! Check the output to see if it is what is expected."
|
||||
end 0
|
Reference in New Issue
Block a user