mirror of
https://gitlab.com/niansa/pilang2.git
synced 2025-03-06 20:49:22 +01:00
Initial commit
This commit is contained in:
commit
d34ada27ee
14 changed files with 801 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
bin
|
27
examples/gettest.pil
Normal file
27
examples/gettest.pil
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#This file is part of pilang.
|
||||||
|
#
|
||||||
|
#pilang 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.
|
||||||
|
#
|
||||||
|
#pilang 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 pilang. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
catch True
|
||||||
|
set userin,$input "Type in something: "
|
||||||
|
|
||||||
|
set charnum,0
|
||||||
|
marker set,printloop
|
||||||
|
sleep 0.1
|
||||||
|
printnnl $get "$~userin,$~charnum"
|
||||||
|
inc charnum
|
||||||
|
cmp bigger,$len $~userin,$~charnum,"marker goto,printloop"
|
||||||
|
|
||||||
|
print
|
||||||
|
marker goto,start
|
35
examples/gettest2.pil
Normal file
35
examples/gettest2.pil
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#This file is part of pilang.
|
||||||
|
#
|
||||||
|
#pilang 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.
|
||||||
|
#
|
||||||
|
#pilang 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 pilang. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
catch True
|
||||||
|
# Store passed arguments as concenated string
|
||||||
|
set argslen,$argc
|
||||||
|
set counter,2
|
||||||
|
set userin,
|
||||||
|
marker set,concatloop
|
||||||
|
# print $~counter, ,$argv $~counter
|
||||||
|
append userin,$argv $~counter," "
|
||||||
|
inc counter
|
||||||
|
cmp smaller,$~counter,$~argslen,"marker goto,concatloop"
|
||||||
|
|
||||||
|
# Print character for character slowly
|
||||||
|
set charnum,0
|
||||||
|
marker set,printloop
|
||||||
|
sleep 0.1
|
||||||
|
printnnl $get "$~userin,$~charnum"
|
||||||
|
inc charnum
|
||||||
|
cmp bigger,$len $~userin,$~charnum,"marker goto,printloop"
|
||||||
|
|
||||||
|
print
|
31
examples/guessinggame.pil
Normal file
31
examples/guessinggame.pil
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#This file is part of pilang.
|
||||||
|
#
|
||||||
|
#pilang 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.
|
||||||
|
#
|
||||||
|
#pilang 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 pilang. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
catch true
|
||||||
|
set number,4
|
||||||
|
|
||||||
|
print "Guess the first number..."
|
||||||
|
marker set,mainloop
|
||||||
|
set guess,$input "Guess a number: "
|
||||||
|
cmp equal,$~guess,,"marker goto,mainloop"
|
||||||
|
cmp isnotnum,$~guess,0,"print That's not a number. Retry with a number!","marker goto,mainloop"
|
||||||
|
cmp bigger,$~guess,$~number,"print Retry with a lower number!","marker goto,mainloop"
|
||||||
|
cmp smaller,$~guess,$~number,"print Retry with a higher number!","marker goto,mainloop"
|
||||||
|
|
||||||
|
print "You guessed it! It's ",$~number,!
|
||||||
|
print "Now guess another number..."
|
||||||
|
|
||||||
|
inc number,7
|
||||||
|
marker goto,mainloop
|
31
examples/simple.pil
Normal file
31
examples/simple.pil
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#This file is part of pilang.
|
||||||
|
#
|
||||||
|
#pilang 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.
|
||||||
|
#
|
||||||
|
#pilang 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 pilang. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# Enable error catching
|
||||||
|
catch True
|
||||||
|
# Initialise stuff
|
||||||
|
set wasword,was
|
||||||
|
# Get input from user
|
||||||
|
set errnonum,Whatever you typed in... It's definitely not a number!!!
|
||||||
|
set name,$input "Name: "
|
||||||
|
cmp equal,$~name,,"print What? That person has no name???",exit 1
|
||||||
|
set birth year,$input "Year of birth: "
|
||||||
|
cmp isnotnum,$~birth year,0,print $~errnonum,exit 3
|
||||||
|
set current year,$input "Current year: "
|
||||||
|
cmp isnotnum,$~current year,0,print $~errnonum,exit 3
|
||||||
|
# Check if birth year is before current year
|
||||||
|
cmp smaller,$~current year,$~birth year,"print Will ,$~name, be born in the future?","set yesno,$input Yes/No?: ","cmp equal,$lower $~yesno,no,exit 4","cmp nonequal,$lower $~yesno,yes,print I give you up... Bye!,exit 4","set wasword,will be"
|
||||||
|
# Print result
|
||||||
|
print $~name, ,$~wasword, born in ,$~birth year, and we are in ,$~current year,",", so I guess ,$~name, is ,$"sub asint,$~current year,$~birth year", years old!
|
566
main.cpp
Normal file
566
main.cpp
Normal file
|
@ -0,0 +1,566 @@
|
||||||
|
/*
|
||||||
|
This file is part of pilang.
|
||||||
|
|
||||||
|
pilang 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.
|
||||||
|
|
||||||
|
pilang 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 pilang. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
#include <exception>
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
#include <regex>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
|
// Return type defs
|
||||||
|
std::string success = "Success";
|
||||||
|
std::string failed = "Failed";
|
||||||
|
std::string nosuchcommand = "No such command";
|
||||||
|
std::string nosuchvariable = "No such variable";
|
||||||
|
std::string badarguments = "Bad arguments";
|
||||||
|
|
||||||
|
// Exception defs
|
||||||
|
class markergoto : public std::string {};
|
||||||
|
std::string markergotoname;
|
||||||
|
|
||||||
|
// Environment defs
|
||||||
|
std::vector<std::string> cmdargs;
|
||||||
|
std::map<std::string, std::string> variables;
|
||||||
|
std::map<std::string, int> markers;
|
||||||
|
bool interactivecli;
|
||||||
|
std::vector<std::string> markersetqueue;
|
||||||
|
std::string execline(std::string commandstr);
|
||||||
|
|
||||||
|
// Helper functions
|
||||||
|
bool is_float(std::string s) {
|
||||||
|
std::istringstream iss(s);
|
||||||
|
float f;
|
||||||
|
iss >> std::noskipws >> f;
|
||||||
|
return iss.eof() && !iss.fail();
|
||||||
|
}
|
||||||
|
std::string str_lower(std::string string) {
|
||||||
|
std::transform(string.begin(), string.end(), string.begin(), ::tolower);
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
std::string str_upper(std::string string) {
|
||||||
|
std::transform(string.begin(), string.end(), string.begin(), ::toupper);
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
std::string ltrim(const std::string& s) {
|
||||||
|
static const std::regex lws{"^[[:space:]]*", std::regex_constants::extended};
|
||||||
|
return std::regex_replace(s, lws, "");
|
||||||
|
}
|
||||||
|
std::string rtrim(const std::string& s) {
|
||||||
|
static const std::regex tws{"[[:space:]]*$", std::regex_constants::extended};
|
||||||
|
return std::regex_replace(s, tws, "");
|
||||||
|
}
|
||||||
|
std::string trim(const std::string& s) {
|
||||||
|
return ltrim(rtrim(s));
|
||||||
|
}
|
||||||
|
std::vector<std::string> strsplit(std::string_view s, char delimiter, std::vector<std::string>::size_type times = 0) {
|
||||||
|
std::vector<std::string> to_return;
|
||||||
|
decltype(s.size()) start = 0, finish = 0;
|
||||||
|
while ((finish = s.find_first_of(delimiter, start)) != std::string_view::npos) {
|
||||||
|
to_return.emplace_back(s.substr(start, finish - start));
|
||||||
|
start = finish + 1;
|
||||||
|
if (to_return.size() == times) { break; }
|
||||||
|
}
|
||||||
|
to_return.emplace_back(s.substr(start));
|
||||||
|
return to_return;
|
||||||
|
}
|
||||||
|
void do_markersetqueue(int currline) {
|
||||||
|
for (const std::string & markername : markersetqueue) {
|
||||||
|
markers[markername] = currline;
|
||||||
|
}
|
||||||
|
markersetqueue = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Builtin functions
|
||||||
|
std::string cmd_ret(std::vector<std::string> args) {
|
||||||
|
std::string retstring;
|
||||||
|
for (const std::string & arg : args){
|
||||||
|
retstring.append(arg);
|
||||||
|
}
|
||||||
|
return retstring;
|
||||||
|
}
|
||||||
|
std::string cmd_get(std::vector<std::string> args) {
|
||||||
|
if (args.size() != 2) {
|
||||||
|
return badarguments;
|
||||||
|
}
|
||||||
|
auto argsit = args.begin();
|
||||||
|
std::string string = *argsit;
|
||||||
|
argsit++;
|
||||||
|
long unsigned int position = std::stoi(*argsit);
|
||||||
|
if (position < string.length()) {
|
||||||
|
std::string res;
|
||||||
|
res.push_back(string.at(position));
|
||||||
|
return res;
|
||||||
|
} else {
|
||||||
|
return badarguments;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::string cmd_len(std::vector<std::string> args) {
|
||||||
|
int result = 0;
|
||||||
|
for (const std::string & arg : args){
|
||||||
|
result += arg.length();
|
||||||
|
}
|
||||||
|
return std::to_string(result);
|
||||||
|
}
|
||||||
|
std::string cmd_exit(std::vector<std::string> args) {
|
||||||
|
//Check amount of arguments
|
||||||
|
if (args.size() != 1) {
|
||||||
|
return badarguments;
|
||||||
|
}
|
||||||
|
std::string exitcode = *args.begin();
|
||||||
|
if (is_float(exitcode))
|
||||||
|
exit(std::stoi(exitcode));
|
||||||
|
else
|
||||||
|
return badarguments;
|
||||||
|
}
|
||||||
|
std::string cmd_marker(std::vector<std::string> args) {
|
||||||
|
// Check amount of arguments
|
||||||
|
if (args.size() != 2) {
|
||||||
|
return badarguments;
|
||||||
|
}
|
||||||
|
// Get arguments
|
||||||
|
auto argsit = args.begin();
|
||||||
|
std::string action = *argsit;
|
||||||
|
argsit++;
|
||||||
|
std::string markername = *argsit;
|
||||||
|
// Set or goto
|
||||||
|
if (action == "goto") {
|
||||||
|
markergotoname = markername;
|
||||||
|
throw markergoto();
|
||||||
|
} else if (action == "set") {
|
||||||
|
markersetqueue.push_back(markername);
|
||||||
|
} else {
|
||||||
|
return badarguments;
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
std::string cmd_printnnl(std::vector<std::string> args) {
|
||||||
|
std::cout << cmd_ret(args) << std::flush;
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
std::string cmd_print(std::vector<std::string> args) {
|
||||||
|
auto result = cmd_printnnl(args);
|
||||||
|
std::cout << std::endl;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
std::string cmd_input(std::vector<std::string> args) {
|
||||||
|
cmd_printnnl(args);
|
||||||
|
std::string result;
|
||||||
|
std::getline(std::cin, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
std::string cmd_set(std::vector<std::string> args) {
|
||||||
|
//Check amount of arguments
|
||||||
|
if (args.size() != 2) {
|
||||||
|
return badarguments;
|
||||||
|
}
|
||||||
|
// Get arguments
|
||||||
|
auto argsit = args.begin();
|
||||||
|
std::string key = *argsit;
|
||||||
|
argsit++;
|
||||||
|
std::string value = *argsit;
|
||||||
|
// Store in environment
|
||||||
|
variables[key] = value;
|
||||||
|
// Return success
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
std::string cmd_append(std::vector<std::string> args) {
|
||||||
|
//Check amount of arguments
|
||||||
|
if (args.size() < 2) {
|
||||||
|
return badarguments;
|
||||||
|
}
|
||||||
|
// Get arguments
|
||||||
|
auto argsit = args.begin();
|
||||||
|
std::string variablename = *argsit;
|
||||||
|
argsit++;
|
||||||
|
for (int dummy; argsit != args.end(); argsit++)
|
||||||
|
variables[variablename].append(*argsit);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
std::string cmd_incdec(bool type, std::vector<std::string> args) {
|
||||||
|
//Check amount of arguments
|
||||||
|
if (args.size() < 1 or args.size() > 2) {
|
||||||
|
return badarguments;
|
||||||
|
}
|
||||||
|
// Get arguments
|
||||||
|
auto argsit = args.begin();
|
||||||
|
std::string variablename = *argsit;
|
||||||
|
float incby;
|
||||||
|
if (args.size() == 2) {
|
||||||
|
argsit++;
|
||||||
|
incby = std::atof((*argsit).c_str());
|
||||||
|
} else {
|
||||||
|
incby = 1;
|
||||||
|
}
|
||||||
|
// Modify variable if it exists
|
||||||
|
if (variables.find(variablename) == variables.end()) {
|
||||||
|
return nosuchvariable;
|
||||||
|
} else {
|
||||||
|
float currval = std::atof(variables[variablename].c_str());
|
||||||
|
if (type)
|
||||||
|
currval += incby;
|
||||||
|
else
|
||||||
|
currval -= incby;
|
||||||
|
variables[variablename] = std::to_string(currval);
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
std::string cmd_del(std::vector<std::string> args) {
|
||||||
|
if (args.size() < 1) {
|
||||||
|
return badarguments;
|
||||||
|
}
|
||||||
|
for (const std::string & arg : args) {
|
||||||
|
auto varit = variables.find(arg);
|
||||||
|
if (varit != variables.end()) {
|
||||||
|
variables.erase(variables.find(arg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
std::string cmd_eval(std::vector<std::string> args) {
|
||||||
|
if (args.size() < 1) {
|
||||||
|
return badarguments;
|
||||||
|
}
|
||||||
|
std::string result;
|
||||||
|
for (const std::string & arg : args) {
|
||||||
|
result = execline(arg);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
std::string cmd_cmp(std::vector<std::string> args) {
|
||||||
|
bool matches;
|
||||||
|
//Check amount of arguments
|
||||||
|
if (args.size() < 4) {
|
||||||
|
return badarguments;
|
||||||
|
}
|
||||||
|
// Get arguments
|
||||||
|
auto argsit = args.begin();
|
||||||
|
std::string action = *argsit;
|
||||||
|
argsit++;
|
||||||
|
std::string var1 = *argsit;
|
||||||
|
argsit++;
|
||||||
|
std::string var2 = *argsit;
|
||||||
|
argsit++;
|
||||||
|
// Compare
|
||||||
|
if (action == "equal")
|
||||||
|
matches = var1 == var2;
|
||||||
|
else if (action == "nonequal")
|
||||||
|
matches = var1 != var2;
|
||||||
|
else if (action == "bigger")
|
||||||
|
matches = std::atof(var1.c_str()) > std::atof(var2.c_str());
|
||||||
|
else if (action == "smaller")
|
||||||
|
matches = std::atof(var1.c_str()) < std::atof(var2.c_str());
|
||||||
|
else if (action == "isnum" or action == "isnotnum") {
|
||||||
|
matches = is_float(var1) and is_float(var2);
|
||||||
|
if (action == "isnotnum")
|
||||||
|
matches = !matches;
|
||||||
|
} else
|
||||||
|
return badarguments;
|
||||||
|
// Eval on match
|
||||||
|
if (matches) {
|
||||||
|
std::string result;
|
||||||
|
while (argsit != args.end()) {
|
||||||
|
result = execline(*argsit);
|
||||||
|
argsit++;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
return failed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::string cmd_lowerupper(bool type, std::vector<std::string> args) {
|
||||||
|
if (args.size() < 1) {
|
||||||
|
return badarguments;
|
||||||
|
}
|
||||||
|
std::string result;
|
||||||
|
for (auto argsit = args.begin(); argsit != args.end(); argsit++) {
|
||||||
|
if (type)
|
||||||
|
result.append(str_upper(*argsit));
|
||||||
|
else
|
||||||
|
result.append(str_lower(*argsit));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
std::string cmd_addsub(bool type, std::vector<std::string> args) {
|
||||||
|
//Check amount of arguments
|
||||||
|
if (args.size() < 2) {
|
||||||
|
return badarguments;
|
||||||
|
}
|
||||||
|
// Initialise variables
|
||||||
|
bool asint = false;
|
||||||
|
float numarg;
|
||||||
|
// Get arguments
|
||||||
|
auto argsit = args.begin();
|
||||||
|
if (*argsit == "asint") {
|
||||||
|
asint = true;
|
||||||
|
argsit++;
|
||||||
|
}
|
||||||
|
// Initialise initial result
|
||||||
|
if (!is_float(*argsit))
|
||||||
|
return badarguments;
|
||||||
|
float result = std::atof((*argsit).c_str());
|
||||||
|
argsit++;
|
||||||
|
// Calculaté
|
||||||
|
for (int dummy; argsit != args.end(); argsit++) {
|
||||||
|
if (!is_float(*argsit))
|
||||||
|
return badarguments;
|
||||||
|
numarg = std::atof((*argsit).c_str());
|
||||||
|
if (type)
|
||||||
|
result += numarg;
|
||||||
|
else
|
||||||
|
result -= numarg;
|
||||||
|
}
|
||||||
|
// Return result
|
||||||
|
if (asint)
|
||||||
|
return std::to_string((int) result);
|
||||||
|
else
|
||||||
|
return std::to_string(result);
|
||||||
|
}
|
||||||
|
std::string cmd_sleep(std::vector<std::string> args) {
|
||||||
|
// Check amount of arguments
|
||||||
|
if (args.size() != 1) {
|
||||||
|
return badarguments;
|
||||||
|
}
|
||||||
|
// Check argument
|
||||||
|
auto argsit = args.begin();
|
||||||
|
if (!is_float(*argsit))
|
||||||
|
return badarguments;
|
||||||
|
// Get argument
|
||||||
|
float sleepnsecs = std::atof((*argsit).c_str()) * 1000000;
|
||||||
|
usleep(sleepnsecs);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
std::string cmd_argv(std::vector<std::string> args) {
|
||||||
|
// Check amount of arguments
|
||||||
|
if (args.size() != 1) {
|
||||||
|
return badarguments;
|
||||||
|
}
|
||||||
|
// Check argument
|
||||||
|
auto argsit = args.begin();
|
||||||
|
if (!is_float(*argsit))
|
||||||
|
return badarguments;
|
||||||
|
long unsigned int argnum = std::atoi((*argsit).c_str());
|
||||||
|
if (argnum >= cmdargs.size())
|
||||||
|
return badarguments;
|
||||||
|
// Get argument
|
||||||
|
return cmdargs[argnum];
|
||||||
|
}
|
||||||
|
std::string cmd_argc(std::vector<std::string> args) {
|
||||||
|
return std::to_string(cmdargs.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string run_command(std::string command, std::vector<std::string> args) {
|
||||||
|
//std::cout << "Running command:" << command << "!" << std::endl;
|
||||||
|
if (command == "ret")
|
||||||
|
return cmd_ret(args);
|
||||||
|
else if (command == "get")
|
||||||
|
return cmd_get(args);
|
||||||
|
else if (command == "len")
|
||||||
|
return cmd_len(args);
|
||||||
|
else if (command == "exit")
|
||||||
|
return cmd_exit(args);
|
||||||
|
else if (command == "marker")
|
||||||
|
return cmd_marker(args);
|
||||||
|
else if (command == "print")
|
||||||
|
return cmd_print(args);
|
||||||
|
else if (command == "printnnl")
|
||||||
|
return cmd_printnnl(args);
|
||||||
|
else if (command == "input")
|
||||||
|
return cmd_input(args);
|
||||||
|
else if (command == "set")
|
||||||
|
return cmd_set(args);
|
||||||
|
else if (command == "append")
|
||||||
|
return cmd_append(args);
|
||||||
|
else if (command == "inc")
|
||||||
|
return cmd_incdec(true, args);
|
||||||
|
else if (command == "dec")
|
||||||
|
return cmd_incdec(false, args);
|
||||||
|
else if (command == "del")
|
||||||
|
return cmd_del(args);
|
||||||
|
else if (command == "eval")
|
||||||
|
return cmd_eval(args);
|
||||||
|
else if (command == "cmp")
|
||||||
|
return cmd_cmp(args);
|
||||||
|
else if (command == "lower")
|
||||||
|
return cmd_lowerupper(false, args);
|
||||||
|
else if (command == "upper")
|
||||||
|
return cmd_lowerupper(true, args);
|
||||||
|
else if (command == "add")
|
||||||
|
return cmd_addsub(true, args);
|
||||||
|
else if (command == "sub")
|
||||||
|
return cmd_addsub(false, args);
|
||||||
|
else if (command == "sleep")
|
||||||
|
return cmd_sleep(args);
|
||||||
|
else if (command == "argv")
|
||||||
|
return cmd_argv(args);
|
||||||
|
else if (command == "argc")
|
||||||
|
return cmd_argc(args);
|
||||||
|
else
|
||||||
|
return "No such command";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interpreter initialiser
|
||||||
|
void init_interpreter(int argc, char *argv[]) {
|
||||||
|
// Load modules from modules directory
|
||||||
|
struct dirent *dp;
|
||||||
|
DIR *dfd;
|
||||||
|
char filename_qfd[264];
|
||||||
|
char moduledir [] = "modules";
|
||||||
|
dfd = opendir(moduledir);
|
||||||
|
while ((dp = readdir(dfd)) != NULL) {
|
||||||
|
sprintf(filename_qfd , "%s/%s",moduledir,dp->d_name);
|
||||||
|
// Skip . and ..
|
||||||
|
if (strcmp(dp->d_name,"..") or strcmp(dp->d_name,"."))
|
||||||
|
continue;
|
||||||
|
// Load file
|
||||||
|
std::cout << "Module loading not yet implemented for: " << filename_qfd << std::endl;
|
||||||
|
}
|
||||||
|
// Generate list of arguments
|
||||||
|
for (int elemnum = 0; elemnum < argc; elemnum++) {
|
||||||
|
cmdargs.push_back(std::string(argv[elemnum]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string execline(std::string commandstr) {
|
||||||
|
commandstr = ltrim(commandstr.substr(0, commandstr.find("#", 0)));
|
||||||
|
//std::cout << "$ " << commandstr << std::endl;
|
||||||
|
if (rtrim(commandstr) == "") { // Command is empty
|
||||||
|
return commandstr;
|
||||||
|
} else if (commandstr.rfind('~', 0) == 0) { // Command is a variable
|
||||||
|
commandstr.erase(0, 1);
|
||||||
|
// Check if variable exists
|
||||||
|
if (variables.find(commandstr) == variables.end()) {
|
||||||
|
return nosuchvariable;
|
||||||
|
} else {
|
||||||
|
return variables[commandstr];
|
||||||
|
}
|
||||||
|
} else { // Command is an actual command
|
||||||
|
std::vector<std::string> cmdsplit = strsplit(commandstr, ' ', 1);
|
||||||
|
auto cmdsplit_it = cmdsplit.begin();
|
||||||
|
std::string command = *cmdsplit_it;
|
||||||
|
std::string argsstr = "";
|
||||||
|
cmdsplit_it++;
|
||||||
|
if (cmdsplit.size() == 2) {
|
||||||
|
argsstr = *cmdsplit_it;
|
||||||
|
argsstr.push_back(',');
|
||||||
|
}
|
||||||
|
std::vector<std::string> args;
|
||||||
|
if (argsstr != ",") {
|
||||||
|
std::string currarg = "";
|
||||||
|
bool instring = false;
|
||||||
|
bool arginstring = false;
|
||||||
|
bool charig = false;
|
||||||
|
bool skipall = false;
|
||||||
|
for (std::string::iterator currchar = argsstr.begin(); currchar < argsstr.end(); currchar++) {
|
||||||
|
if (skipall) {
|
||||||
|
continue;
|
||||||
|
} else if (*currchar == '"' and !skipall) {
|
||||||
|
instring = !instring;
|
||||||
|
if (currarg == "")
|
||||||
|
arginstring = true;
|
||||||
|
} else if (*currchar == '#' and !charig and !instring) {
|
||||||
|
skipall = true;
|
||||||
|
} else if (*currchar == ',' and !charig and !instring) {
|
||||||
|
if (currarg.length() != 0 and *currarg.begin() == '$' and !arginstring) {
|
||||||
|
currarg.erase(0, 1);
|
||||||
|
currarg = execline(currarg);
|
||||||
|
}
|
||||||
|
args.push_back(currarg);
|
||||||
|
currarg = "";
|
||||||
|
arginstring = false;
|
||||||
|
} else if (*currchar == '\\' and !charig) {
|
||||||
|
charig = true;
|
||||||
|
} else {
|
||||||
|
currarg.push_back(*currchar);
|
||||||
|
charig = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//std::cout << "Args len: " << args.size() << std::endl;
|
||||||
|
return run_command(command, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Main CLI
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
std::string line;
|
||||||
|
using namespace std;
|
||||||
|
if (argc == 1) { // Start interactive CLI
|
||||||
|
// Show copyright note
|
||||||
|
cout << "pilang Copyright (C) 2020 niansa" << endl;
|
||||||
|
cout << "This program comes with ABSOLUTELY NO WARRANTY; for details type `warranty'." << endl;
|
||||||
|
cout << "This is free software, and you are welcome to redistribute it" << endl;
|
||||||
|
cout << "under certain conditions; type `license' for details." << endl;
|
||||||
|
cout << endl;
|
||||||
|
// Initialise stuff
|
||||||
|
init_interpreter(argc, argv);
|
||||||
|
interactivecli = true;
|
||||||
|
// Input loop
|
||||||
|
while (true) {
|
||||||
|
line = "";
|
||||||
|
cout << ">>> " << flush;
|
||||||
|
std::getline(std::cin, line);
|
||||||
|
cout << execline(line) << endl;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Read from argv[1] into vector
|
||||||
|
std::ifstream scriptfile(argv[1]);
|
||||||
|
std::vector<std::string> lines;
|
||||||
|
std::string line;
|
||||||
|
while (std::getline(scriptfile, line)) {
|
||||||
|
lines.push_back(line);
|
||||||
|
if (scriptfile.eof()) { break; } // EOF
|
||||||
|
}
|
||||||
|
scriptfile.close();
|
||||||
|
// Initialise stuff
|
||||||
|
init_interpreter(argc, argv);
|
||||||
|
interactivecli = false;
|
||||||
|
// Add initial marker in line 0
|
||||||
|
markersetqueue.push_back("start");
|
||||||
|
do_markersetqueue(0);
|
||||||
|
// Execute vector line-by-line
|
||||||
|
auto linesit = lines.begin();
|
||||||
|
for (int currline = 0; linesit != lines.end(); currline++) {
|
||||||
|
try {
|
||||||
|
execline(*linesit);
|
||||||
|
do_markersetqueue(currline); // Do markerqueue
|
||||||
|
} catch (markergoto) { // Catch marker goto
|
||||||
|
do_markersetqueue(currline); // Do markerqueue even if an exception occured
|
||||||
|
if (markers.find(markergotoname) != markers.end()) {
|
||||||
|
currline = markers[markergotoname];
|
||||||
|
linesit = lines.begin() + currline;
|
||||||
|
} else {
|
||||||
|
cerr << "No such marker: \"" << markergotoname << "\" (critical)" << endl;
|
||||||
|
return 77;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
linesit++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
BIN
obj/Debug/main.o
Normal file
BIN
obj/Debug/main.o
Normal file
Binary file not shown.
BIN
obj/Debug/src/environment.o
Normal file
BIN
obj/Debug/src/environment.o
Normal file
Binary file not shown.
BIN
obj/Debug/src/interpreter.o
Normal file
BIN
obj/Debug/src/interpreter.o
Normal file
Binary file not shown.
BIN
obj/Debug/src/module_builtin.o
Normal file
BIN
obj/Debug/src/module_builtin.o
Normal file
Binary file not shown.
BIN
obj/Debug/src/rtypes.o
Normal file
BIN
obj/Debug/src/rtypes.o
Normal file
Binary file not shown.
43
pilang.cbp
Normal file
43
pilang.cbp
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||||
|
<CodeBlocks_project_file>
|
||||||
|
<FileVersion major="1" minor="6" />
|
||||||
|
<Project>
|
||||||
|
<Option title="pilang" />
|
||||||
|
<Option pch_mode="2" />
|
||||||
|
<Option compiler="gcc" />
|
||||||
|
<Build>
|
||||||
|
<Target title="Debug">
|
||||||
|
<Option output="bin/Debug/pilang" prefix_auto="1" extension_auto="1" />
|
||||||
|
<Option object_output="obj/Debug/" />
|
||||||
|
<Option type="1" />
|
||||||
|
<Option compiler="gcc" />
|
||||||
|
<Compiler>
|
||||||
|
<Add option="-g" />
|
||||||
|
<Add directory="include" />
|
||||||
|
</Compiler>
|
||||||
|
</Target>
|
||||||
|
<Target title="Release">
|
||||||
|
<Option output="bin/Release/pilang" prefix_auto="1" extension_auto="1" />
|
||||||
|
<Option object_output="obj/Release/" />
|
||||||
|
<Option type="1" />
|
||||||
|
<Option compiler="gcc" />
|
||||||
|
<Compiler>
|
||||||
|
<Add option="-O2" />
|
||||||
|
<Add directory="include" />
|
||||||
|
</Compiler>
|
||||||
|
<Linker>
|
||||||
|
<Add option="-s" />
|
||||||
|
</Linker>
|
||||||
|
</Target>
|
||||||
|
</Build>
|
||||||
|
<Compiler>
|
||||||
|
<Add option="-Wall" />
|
||||||
|
<Add option="-fexceptions -std=c++17" />
|
||||||
|
</Compiler>
|
||||||
|
<Unit filename="main.cpp" />
|
||||||
|
<Extensions>
|
||||||
|
<code_completion />
|
||||||
|
<debugger />
|
||||||
|
</Extensions>
|
||||||
|
</Project>
|
||||||
|
</CodeBlocks_project_file>
|
57
pilang.depend
Normal file
57
pilang.depend
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
# depslib dependency file v1.0
|
||||||
|
1586773944 source:/home/nils/Programme/OSS/codeblocks/pilang/main.cpp
|
||||||
|
<iostream>
|
||||||
|
<string>
|
||||||
|
<string_view>
|
||||||
|
<exception>
|
||||||
|
<map>
|
||||||
|
<vector>
|
||||||
|
<regex>
|
||||||
|
<fstream>
|
||||||
|
<cstdio>
|
||||||
|
<cstring>
|
||||||
|
<dlfcn.h>
|
||||||
|
<dirent.h>
|
||||||
|
|
||||||
|
1586692463 /home/nils/Programme/OSS/codeblocks/pilang/include/interpreter.h
|
||||||
|
<rtypes.h>
|
||||||
|
<map>
|
||||||
|
<list>
|
||||||
|
<functional>
|
||||||
|
|
||||||
|
1586614898 source:/home/nils/Programme/OSS/codeblocks/pilang/src/environment.cpp
|
||||||
|
"environment.h"
|
||||||
|
|
||||||
|
1586614630 /home/nils/Programme/OSS/codeblocks/pilang/include/environment.h
|
||||||
|
<map>
|
||||||
|
|
||||||
|
1586691513 source:/home/nils/Programme/OSS/codeblocks/pilang/src/interpreter.cpp
|
||||||
|
<iostream>
|
||||||
|
<map>
|
||||||
|
<list>
|
||||||
|
<cstdio>
|
||||||
|
<cstring>
|
||||||
|
<dlfcn.h>
|
||||||
|
<dirent.h>
|
||||||
|
<interpreter.h>
|
||||||
|
<environment.h>
|
||||||
|
|
||||||
|
1586690920 source:/home/nils/Programme/OSS/codeblocks/pilang/src/module_builtin.cpp
|
||||||
|
"module_builtin.h"
|
||||||
|
<iostream>
|
||||||
|
<list>
|
||||||
|
<string>
|
||||||
|
|
||||||
|
1586690835 /home/nils/Programme/OSS/codeblocks/pilang/include/module_builtin.h
|
||||||
|
<rtypes.h>
|
||||||
|
<map>
|
||||||
|
<list>
|
||||||
|
<string>
|
||||||
|
|
||||||
|
1586690671 /home/nils/Programme/OSS/codeblocks/pilang/include/rtypes.h
|
||||||
|
<list>
|
||||||
|
<string>
|
||||||
|
|
||||||
|
1586687677 source:/home/nils/Programme/OSS/codeblocks/pilang/src/rtypes.cpp
|
||||||
|
"rtypes.h"
|
||||||
|
|
10
pilang.layout
Normal file
10
pilang.layout
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||||
|
<CodeBlocks_layout_file>
|
||||||
|
<FileVersion major="1" minor="0" />
|
||||||
|
<ActiveTarget name="Debug" />
|
||||||
|
<File name="main.cpp" open="1" top="1" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||||
|
<Cursor>
|
||||||
|
<Cursor1 position="3641" topLine="119" />
|
||||||
|
</Cursor>
|
||||||
|
</File>
|
||||||
|
</CodeBlocks_layout_file>
|
Loading…
Add table
Reference in a new issue