sencha-lang/Sencha-lang/main.cpp

146 lines
3.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 "ContextManager.h"
#include "ASTInspector.h"
#include "Tests/tests.h"
#include "basic_native_functions.h"
#include <unistd.h>
using namespace std;
//Helper functions
void register_functions(ContextManager & context_manager)
{
context_manager.context("global")->register_function("print", print);
context_manager.context("global")->register_function("println", println);
context_manager.context("global")->register_function("sin", s_sin);
context_manager.context("global")->register_function("cos", s_cos);
context_manager.context("global")->register_function("tan", s_tan);
context_manager.context("global")->register_function("sleep", sleep);
context_manager.context("global")->register_function("len", len);
}
string compute_indentation(int depth_level)
{
string indent = "";
for(int i=0; i< depth_level; i++)
{
indent += " ";
}
return indent;
}
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;
}
void interactive()
{
//Initialization
Lexer lexer;
ContextManager context_manager;
register_functions(context_manager);
Parser parser(&context_manager);
ASTInspector inspector;
vector<Token> tokens;
string input;
int level_of_depth = 0;
string indentation = "";
//Main loop of interactive mode
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);
//It executes when statements and braces are closed
if(level_of_depth == 0) {
parser.interpret();
parser.program->execute_last();
inspector.visit(parser.tree.root);
cout << context_manager.get_top()->debug() << endl;
//cout << parser.show_tokens();
cout << inspector.get_report();
inspector.forget_everything();
}
}
}
void execute_script(std::string name )
{
Lexer lexer;
ContextManager context_manager;
register_functions(context_manager);
Parser parser(&context_manager);
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();
}
/**
* Main function resolves in which mode user want to run program
* Modes are:
* Interactive - it is run when no arguments are provided
* Tests - "SenchaLang --test"
* Script execution - if path provided
*/
int main(int argc, char *argv[])
{
if(argc <= 1)
{
cout << "Sencha-lang interpreter, version 0.44" << endl;
interactive();
}
else
{
std::string argument1 = argv[1];
if(argument1 == "--test")
{
cout << "I'm running tests" << endl;
run_tests();
}
else {
execute_script(argument1);
}
}
return 0;
}