sencha-lang/Sencha-lang/main.cpp

213 lines
4.1 KiB
C++

#include <fstream>
#include <iostream>
#include <string>
#include <math.h>
#include "Token.h"
#include "Lexer.h"
#include "Parser.h"
#include "Tests/TestLexer.h"
#include "Context.h"
#include "Tests/tests.h"
using namespace std;
/*TODO
* Known bugs:
*
* >> print("I like bananas", dupa");
I like bananasnull
Context: 0: dupa"); type: null
null
dupa"); declaration? hello? It's probably temporary effect of searching for this name in variable tables
>>
*/
SenchaObject print(vector<ASTExpression *> arguments)
{
for (auto argument: arguments)
{
auto value = argument->evaluate();
std::cout << value.str();
}
std::cout << std::endl;
return SenchaObject();
}
SenchaObject s_sin(vector<ASTExpression *> arguments)
{
SenchaObject result;
SenchaObject sin_argument = arguments[0]->evaluate();
if(sin_argument.type == SenchaObject::integer_number)
{
result = SenchaObject(sin(sin_argument.integer));
}
else if(sin_argument.type == SenchaObject::float_number)
{
result = SenchaObject(sin(sin_argument.number));
}
else
{
result.type = SenchaObject::invalid;
}
return result;
}
SenchaObject s_cos(vector<ASTExpression *> arguments)
{
SenchaObject result;
SenchaObject cos_argument = arguments[0]->evaluate();
if(cos_argument.type == SenchaObject::integer_number)
{
result = SenchaObject(cos(cos_argument.integer));
}
else if(cos_argument.type == SenchaObject::float_number)
{
result = SenchaObject(cos(cos_argument.number));
}
else
{
result.type = SenchaObject::invalid;
}
return result;
}
SenchaObject s_tan(vector<ASTExpression *> arguments)
{
SenchaObject result;
SenchaObject tan_argument = arguments[0]->evaluate();
if(tan_argument.type == SenchaObject::integer_number)
{
result = SenchaObject(tan(tan_argument.integer));
}
else if(tan_argument.type == SenchaObject::float_number)
{
result = SenchaObject(tan(tan_argument.number));
}
else
{
result.type = SenchaObject::invalid;
}
return result;
}
int how_depth_change(vector<Token> tokens)
{
int change = 0;
for (unsigned int i = 0; i < tokens.size(); i++)
{
if(tokens[i].value == "{") change++;
else if(tokens[i].value == "}") change--;
}
return change;
}
string compute_indentation(int depth_level)
{
string indent = "";
for(int i=0; i< depth_level; i++)
{
indent += " ";
}
return indent;
}
void interactive()
{
Lexer lexer;
Context context;
context.register_function("print", print);
context.register_function("sin", s_sin);
context.register_function("cos", s_cos);
context.register_function("tan", s_tan);
Parser parser(&context);
vector<Token> tokens;
string input;
int level_of_depth = 0;
string indentation = "";
while(true)
{
cout << ">> " + indentation;
getline(cin, input);
if(input == "quit()") break;
tokens = lexer.parse_line(input);
level_of_depth += how_depth_change(tokens);
indentation = compute_indentation(level_of_depth);
parser.add_tokens(tokens);
if(level_of_depth == 0) {
parser.interpret();
parser.program->execute_last();
//cout << parser.report_message << endl;
//cout << parser.error_message << endl;
//cout << parser.show_tokens() << endl;
//cout << "My tree:\n";
//cout << parser.program->debug();
cout << parser.context->debug();
}
}
}
int main(int argc, char *argv[])
{
if(argc <= 1)
{
cout << "Sencha-lang interpreter, version 0.12" << endl;
interactive();
}
else
{
std::string argument1 = argv[1];
if(argument1 == "--test") {
cout << "I'm running tests" << endl;
run_tests();
}
else {
auto name = argument1;
Lexer lexer;
Context context;
context.register_function("print", print);
context.register_function("sin", s_sin);
context.register_function("cos", s_cos);
context.register_function("tan", s_tan);
Parser parser(&context);
vector<Token> tokens;
string line;
ifstream input_file (name);
if (input_file.is_open())
{
while ( input_file.good() )
{
getline (input_file,line);
tokens = lexer.parse_line(line);
parser.add_tokens(tokens);
}
input_file.close();
}
parser.interpret();
parser.program->execute();
}
}
return 0;
}