summaryrefslogtreecommitdiffstats
path: root/Sencha-lang/main.cpp
blob: 01fea68b3b6f2db271e4560478630cdeed24df4c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#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;
}