/* Ground Copyright (C) 2025 Maxwell Jeffress 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 . */ /* With the licence out of the way, let's begin! Ground is a programming language which takes some inspiration from Assembly in its design, but has higher level features (more types, simpler IO, easier variables, etc) which makes it easy to use. Ground works even better if you write a programming language that compiles to Ground code. Ground is designed to have a similar purpose to the Java Virtual Machine, except easier for anyone to write their own highly opinionated language on top of. See documentation for building, maintaining and writing Ground code in the docs folder in the repo. Happy coding! */ #include #include #include #include #include #include #include #include #include // Headers for external libraries #ifdef _WIN32 // Note: Windows support is experiemental. Maybe try using a superior // operating system? (cough cough, Linux?) #include #define DLOPEN(path) LoadLibrary(path) #define DLSYM(handle, name) GetProcAddress(handle, name) #define DLCLOSE(handle) FreeLibrary(handle) #define DLERROR() "Windows DLL Error" #else #include #define DLOPEN(path) dlopen(path, RTLD_LAZY) #define DLSYM(handle, name) dlsym(handle, name) #define DLCLOSE(handle) dlclose(handle) #define DLERROR() dlerror() #endif using namespace std; /* Instructions enum class For each function keyword, an instruction is assigned. See also parser function, interpreter function, Instruction struct */ enum class Instructions { Jump, If, Stdout, Stdin, Stdlnout, Add, Subtract, Multiply, Divide, Equal, Inequal, Greater, Lesser, Not, End, Set, Empty, Gettype, Exists, Setlist, Getlistat, Setlistat, Getlistsize, Listappend, Listprepend, Getstrcharat, Getstrsize, Stoi, Stod, Tostring, Fun, Return, Endfun, Pusharg, Call, Local, Use, Extern }; /* Types enum class Assists in type checking in the parser function. For example, the following values correspond to the following types: 1 Int 3.14 Double "Hello!" String 'e' Char true Bool $value Value &var Direct %10 Line See also parser function */ enum class Types { Int, Double, String, Char, Bool, Value, Direct, Line, List, ListRef, Label, Type, Function }; // Forward declaration of Literal for list struct Literal; /* List struct Contains literal values inside a vector. For example, if the following program was written: setlist #myNums 3 5 9 13 The List struct which would be created and stored should look like this: { val = { Literal { val = 3 }, Literal { val = 5 }, Literal { val = 9 }, Literal { val = 13 }, } } All elements in the list must be of the same type. See also Literal struct. */ struct List { vector val; }; /* Literal struct Contains literal values. For example, if the following line was written: stdout "Hello world!" The Literal struct in the instruction should look like this: { val = "Hello world!"; // I am ignoring the variant for simplicity // of documenting the code } All value references are swapped out for their respective Literal they point to. See also variables map, parser function, interpreter function */ struct Literal { variant val; }; /* Direct struct If the program being executed makes a direct reference, it is stored in a Direct struct. For example, if the following line was written: stdin &myVar The Direct struct in the instruction should look like this: { varName = "myVar"; } */ struct Direct { string varName; }; struct TypeRef { Types type; }; struct FunctionRef { string fnName; }; /* Label struct Contains information needed to register labels */ struct Label { string id; int lineNum = -1; }; /* Line struct Contains information needed to jump to lines */ struct Line { int lineNum = -1; bool isLabel = false; string label; }; /* labelStack stack Allows each function to hold it's own set of labels */ stack> labelStack; /* ListRef struct Contains the name of a list referenced by the program. For example, if the following program was written: setlist #myNums 3 5 9 13 The ListRef struct should look like this: { listName = "myNums"; } */ struct ListRef { string listName; }; /* variables map Contains all variables made while running the program. See also Literal struct. */ map variables; /* ValueRef struct If the program being executed makes a value reference, it is stored in a ValueRef struct. For example, if the following line was written: stdin &myVar The ValueRef struct in the instruction should look like this: { varName = "myVar"; } */ struct ValueRef { string varName; }; /* Instruction struct An instruction usually corresponds to a line in the program being interpreted. For example, if the following line was written: add 5 $myVar &outVar The instruction should look like this: { inst = Instructions::Add; args = { Literal { val = 5 }, ValueRef { varName = "myVar" }, Direct { varName = "outVar" } }; } inst starts as empty, so empty lines and commented out lines do not get in the way of jump and if. See also: Instructions enum class, Literal struct, ValueRef struct, Direct struct, Line struct, exec function, parser function */ typedef variant argument; struct Instruction { Instructions inst = Instructions::Empty; vector args; bool isLabel = false; Label label; }; struct FnArg { Direct ref; Types type; }; /* Function struct Contains information needed to run a Ground function. */ struct Function { Types returnType; vector args; vector instructions; vector