Skip to content

Commit 3322356

Browse files
Add files via upload
1 parent f44a3e1 commit 3322356

12 files changed

Lines changed: 270 additions & 50 deletions

File tree

src/builtins.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "errors.h"
66
#include "value.h"
77
#include "references.h"
8+
#include "collection.h"
89
#include "garbage.h"
910

1011
typedef reference_apartment* (*built_in_function)(std::list<value*> arguments, garbage_collector* gc);
@@ -19,4 +20,26 @@ inline void match_arg_type(value* value, char expected_type) {
1920
throw ERROR_INVALID_VALUE_TYPE;
2021
}
2122

23+
inline char* to_c_str(value* value) {
24+
match_arg_type(value, VALUE_TYPE_COLLECTION);
25+
collection* collection = (class collection*)value->ptr;
26+
char* c = new char[collection->size + 1];
27+
for (size_t i = 0; i < collection->size; i++)
28+
{
29+
match_arg_type(collection->get_value(i), VALUE_TYPE_CHAR);
30+
c[i] = *collection->get_value(i)->get_char();
31+
}
32+
c[collection->size] = 0;
33+
return c;
34+
}
35+
36+
inline collection* from_c_str(const char* str, garbage_collector* gc) {
37+
collection* str_col = new collection(strlen(str), gc);
38+
for (size_t i = 0; i < str_col->size; i++)
39+
{
40+
str_col->set_value(i, new value(VALUE_TYPE_CHAR, new char(str[i])));
41+
}
42+
return str_col;
43+
}
44+
2245
#endif // !BUILTINS_H

src/collection.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class collection {
3737

3838
collection* clone(reference_apartment* parent_reference);
3939

40-
inline reference_apartment* get_parent() {
40+
inline reference_apartment* get_parent_ref() {
4141
return this->parent_reference;
4242
}
4343

src/io.cpp

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
#include "errors.h"
2+
#include "structure.h"
3+
#include "collection.h"
4+
#include "tokens.h"
5+
#include "builtins.h"
6+
#include "io.h"
7+
8+
#include <fstream>
9+
#include <iostream>
10+
#include <stack>
11+
12+
void handle_syntax_err(int syntax_error, unsigned int pos, const char* source) {
13+
std::cout << std::endl << "***Syntax Error: " << get_err_info(syntax_error) << "***" << std::endl;
14+
std::cout << "Error Code: " << syntax_error << '\t' << "Lexer Index: " << pos << std::endl;
15+
for (int i = (int)pos - (int)17 > 0 ? pos - 17 : 0; i < strlen(source) && i < pos + 17; i++) {
16+
std::cout << source[i];
17+
}
18+
std::cout << "" << std::endl;
19+
}
20+
21+
void handle_runtime_err(int runtime_error, token* err_tok) {
22+
std::cout << std::endl << "***Runtime Error: " << get_err_info(runtime_error) << "***" << std::endl;
23+
std::cout << "Error Code: " << runtime_error << '\t' << "Error Tok Type: " << (int)err_tok->type << std::endl;
24+
}
25+
26+
void print_call_stack(std::stack<function_prototype*> call_stack) {
27+
std::cout << std::endl << "Stack Trace:";
28+
if (call_stack.empty()) {
29+
std::cout << " Empty";
30+
return;
31+
}
32+
while (!call_stack.empty())
33+
{
34+
std::cout << std::endl << "\tin " << call_stack.top()->identifier->get_identifier();
35+
call_stack.pop();
36+
}
37+
}
38+
39+
void print_value(value* val);
40+
41+
inline void print_indent(unsigned int indent) {
42+
for (size_t i = 0; i < indent; i++)
43+
std::cout << '\t';
44+
}
45+
46+
void xprint(structure* structure, unsigned int indent) {
47+
print_indent(indent);
48+
std::cout << '<'<< structure->get_identifier()->get_identifier() << '>';
49+
reference_apartment** children = structure->get_children();
50+
for (size_t i = 0; i < structure->get_size(); i++)
51+
{
52+
std::cout << std::endl;
53+
if (children[i]->value->type != VALUE_TYPE_STRUCT) {
54+
print_indent(indent + 1);
55+
print_value(children[i]->value);
56+
}
57+
else {
58+
xprint((class structure*)children[i]->value->ptr, indent + 1);
59+
}
60+
}
61+
}
62+
63+
void print_array(collection* collection) {
64+
bool is_str = true;
65+
for (size_t i = 0; i < collection->size; i++)
66+
{
67+
if (collection->get_value(i)->type != VALUE_TYPE_CHAR) {
68+
is_str = false;
69+
break;
70+
}
71+
}
72+
if (is_str) {
73+
for (size_t i = 0; i < collection->size; i++)
74+
{
75+
std::cout << *collection->get_value(i)->get_char();
76+
}
77+
}
78+
else {
79+
if (collection->size > 25) {
80+
std::cout << "<array>";
81+
return;
82+
}
83+
std::cout << '[';
84+
for (size_t i = 0; i < collection->size; i++)
85+
{
86+
print_value(collection->get_value(i));
87+
if (i != collection->size - 1)
88+
std::cout << ", ";
89+
}
90+
std::cout << ']';
91+
}
92+
}
93+
94+
void print_value(value* val) {
95+
switch (val->type)
96+
{
97+
case VALUE_TYPE_NULL:
98+
std::cout << "null";
99+
break;
100+
case VALUE_TYPE_CHAR:
101+
std::cout << *val->get_char();
102+
break;
103+
case VALUE_TYPE_NUMERICAL:
104+
std::cout << *val->get_numerical();
105+
break;
106+
case VALUE_TYPE_COLLECTION:
107+
print_array((collection*)val->ptr);
108+
break;
109+
case VALUE_TYPE_STRUCT:
110+
//std::cout << '<' << ((structure*)val->ptr)->get_identifier()->get_identifier() << '>';
111+
xprint((structure*)val->ptr, 0);
112+
break;
113+
default:
114+
throw ERROR_INVALID_VALUE_TYPE;
115+
}
116+
}
117+
118+
reference_apartment* print(std::list<value*> arguments, garbage_collector* gc) {
119+
for (auto it = arguments.begin(); it != arguments.end(); ++it) {
120+
print_value(*it);
121+
}
122+
return gc->new_apartment(new value(VALUE_TYPE_NULL, nullptr));
123+
}
124+
125+
reference_apartment* print_line(std::list<value*> arguments, garbage_collector* gc) {
126+
reference_apartment* appt = print(arguments, gc);
127+
std::cout << std::endl;
128+
return appt;
129+
}
130+
131+
reference_apartment* get_input(std::list<value*> arguments, garbage_collector* gc) {
132+
char* input = new char[250];
133+
std::cin.getline(input, 250);
134+
collection* str = from_c_str(input, gc);
135+
return str->get_parent_ref();
136+
}
137+
138+
reference_apartment* file_read_text(std::list<value*> args, garbage_collector* gc) {
139+
match_arg_len(args, 1);
140+
match_arg_type(args.front(), VALUE_TYPE_COLLECTION);
141+
142+
char* file_path = to_c_str(args.front());
143+
144+
std::ifstream infile(file_path, std::ifstream::binary);
145+
146+
if (!infile.is_open())
147+
return gc->new_apartment(new value(VALUE_TYPE_NUMERICAL, new long double(0)));
148+
delete[] file_path;
149+
150+
infile.seekg(0, std::ios::end);
151+
int buffer_length = infile.tellg();
152+
infile.seekg(0, std::ios::beg);
153+
char* buffer = new char[buffer_length + 1];
154+
infile.read(buffer, buffer_length);
155+
infile.close();
156+
buffer[buffer_length] = 0;
157+
158+
collection* strcol = from_c_str(buffer, gc);
159+
delete[] buffer;
160+
return strcol->get_parent_ref();
161+
}
162+
163+
reference_apartment* file_write_text(std::list<value*> args, garbage_collector* gc) {
164+
match_arg_len(args, 2);
165+
match_arg_type(args.front(), VALUE_TYPE_COLLECTION);
166+
match_arg_type(args.back(), VALUE_TYPE_COLLECTION);
167+
168+
char* file_path = to_c_str(args.front());
169+
170+
std::ofstream infile(file_path, std::ofstream::binary);
171+
172+
if(!infile.is_open())
173+
return gc->new_apartment(new value(VALUE_TYPE_NUMERICAL, new long double(0)));
174+
delete[] file_path;
175+
176+
char* buffer = to_c_str(args.back());
177+
infile.write(buffer, strlen(buffer));
178+
infile.close();
179+
delete[] buffer;
180+
181+
return gc->new_apartment(new value(VALUE_TYPE_NUMERICAL, new long double(1)));
182+
}

src/io.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#pragma once
2+
3+
#ifndef IO_H
4+
#define IO_H
5+
6+
#include <list>
7+
#include "tokens.h"
8+
#include "references.h"
9+
#include "value.h"
10+
11+
reference_apartment* print(std::list<value*> arguments, garbage_collector* gc);
12+
reference_apartment* print_line(std::list<value*> arguments, garbage_collector* gc);
13+
reference_apartment* get_input(std::list<value*> arguments, garbage_collector* gc);
14+
15+
reference_apartment* file_read_text(std::list<value*> args, garbage_collector* gc);
16+
reference_apartment* file_write_text(std::list<value*> args, garbage_collector* gc);
17+
18+
void handle_syntax_err(int syntax_error, unsigned int pos, const char* source);
19+
void handle_runtime_err(int runtime_error, token* err_tok);
20+
void print_call_stack(std::stack<function_prototype*> call_stack);
21+
22+
#endif // !IO_H

src/lexer.cpp

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -334,9 +334,6 @@ token* lexer::tokenize_statement(bool interactive_mode) {
334334
}
335335
delete[] lexer_state->group_stack.back();
336336
lexer_state->group_stack.pop_back();
337-
for (auto i = lexer_state->to_exclude.begin(); i != lexer_state->to_exclude.end(); ++i)
338-
lexer_state->namespace_register.insert(*i);
339-
lexer_state->to_exclude.clear();
340337
read_token();
341338
return nullptr;
342339
case TOKEN_CONST_KW: {
@@ -386,6 +383,7 @@ token* lexer::tokenize_statement(bool interactive_mode) {
386383
case TOKEN_UNIARY_OP:
387384
case TOKEN_VALUE:
388385
case OP_SUBTRACT:
386+
case OP_INVERT:
389387
if (interactive_mode) {
390388
return print_encapsulate(tokenize_expression());
391389
}
@@ -429,7 +427,7 @@ token* lexer::tokenize_statement(bool interactive_mode) {
429427
case TOKEN_STRUCT_KW: {
430428
delete last_tok;
431429
match_tok(read_token(), TOKEN_IDENTIFIER);
432-
identifier_token* proto_id = apply_groups((identifier_token*)last_tok, true);
430+
identifier_token* proto_id = apply_groups((identifier_token*)last_tok);
433431
match_tok(read_token(), TOKEN_OPEN_BRACE);
434432
delete last_tok;
435433
std::list<identifier_token*> properties;
@@ -447,7 +445,7 @@ token* lexer::tokenize_statement(bool interactive_mode) {
447445
case TOKEN_FUNC_KW: {
448446
delete last_tok;
449447
match_tok(read_token(), TOKEN_IDENTIFIER);
450-
identifier_token* proto_id = apply_groups((identifier_token*)last_tok, true);
448+
identifier_token* proto_id = apply_groups((identifier_token*)last_tok);
451449
match_tok(read_token(), TOKEN_OPEN_PARAM);
452450
delete last_tok;
453451
std::list<identifier_token*> params;
@@ -535,17 +533,7 @@ variable_access_token* lexer::tokenize_var_access(identifier_token* identifier)
535533
return new variable_access_token(toks);
536534
}
537535

538-
identifier_token* lexer::apply_groups(identifier_token* id, bool creating) {
539-
if (lexer_state->group_stack.empty()) {
540-
if (creating) {
541-
lexer_state->namespace_register.insert(id->id_hash);
542-
}
543-
return id;
544-
}
545-
else if(lexer_state->namespace_register.count(id->id_hash)) {
546-
return id;
547-
}
548-
536+
identifier_token* lexer::apply_groups(identifier_token* id) {
549537
char* base_id = (char*)id->get_identifier();
550538
id->no_delete();
551539
delete id;
@@ -569,9 +557,6 @@ identifier_token* lexer::apply_groups(identifier_token* id, bool creating) {
569557

570558
identifier_token* new_id = new identifier_token(id_buf, insecure_hash(id_buf));
571559

572-
if (creating)
573-
lexer_state->to_exclude.push_back(new_id->id_hash);
574-
575560
return new_id;
576561
}
577562

@@ -597,7 +582,6 @@ token* lexer::tokenize_value() {
597582
match_tok(last_tok, TOKEN_CLOSE_PARAM);
598583
delete last_tok;
599584
read_token();
600-
identifier = apply_groups(identifier, false);
601585
return new function_call_token(identifier, arguments);
602586
}
603587
else
@@ -662,7 +646,7 @@ token* lexer::tokenize_value() {
662646
else if (last_tok->type == TOKEN_NEW_KW) {
663647
delete last_tok;
664648
match_tok(read_token(), TOKEN_IDENTIFIER);
665-
create_struct_token* new_struct = new create_struct_token(apply_groups((identifier_token*)last_tok, false));
649+
create_struct_token* new_struct = new create_struct_token((identifier_token*)last_tok);
666650
read_token();
667651
return new_struct;
668652
}

src/lexer.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@
1212

1313
struct lexer_state {
1414
std::map<unsigned long, value*> constants;
15-
std::set<unsigned long> namespace_register;
1615
std::list<char*> group_stack;
17-
std::list<unsigned long> to_exclude;
1816

1917
~lexer_state() {
2018
for (auto it = this->constants.begin(); it != this->constants.end(); ++it)
@@ -64,7 +62,7 @@ class lexer {
6462
token* read_token();
6563
token* tokenize_statement(bool interactive_mode);
6664
std::list<token*> tokenize_body();
67-
identifier_token* apply_groups(identifier_token* id, bool creating);
65+
identifier_token* apply_groups(identifier_token* id);
6866
variable_access_token* tokenize_var_access();
6967
variable_access_token* tokenize_var_access(identifier_token* identifier);
7068
token* tokenize_expression(unsigned char min = 0);

src/linq.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ reference_apartment* allocate_array(std::list<value*> arguments, garbage_collect
1313
unsigned long req_size = (unsigned long)*arguments.front()->get_numerical();
1414

1515
collection* allocated_array = new collection(req_size, gc);
16-
return allocated_array->get_parent();
16+
return allocated_array->get_parent_ref();
1717
}
1818

1919
reference_apartment* get_length(std::list<value*> arguments, garbage_collector* gc) {
@@ -22,4 +22,19 @@ reference_apartment* get_length(std::list<value*> arguments, garbage_collector*
2222

2323
collection* collection = (class collection*)arguments.front()->ptr;
2424
return gc->new_apartment(new value(VALUE_TYPE_NUMERICAL, new long double((long double)collection->size)));
25+
}
26+
27+
reference_apartment* count_instances(std::list<value*> arguments, garbage_collector* gc) {
28+
match_arg_len(arguments, 2);
29+
match_arg_type(arguments.front(), VALUE_TYPE_COLLECTION);
30+
31+
collection* collection = (class collection*)arguments.front()->ptr;
32+
unsigned int instances = 0;
33+
34+
for (size_t i = 0; i < collection->size; i++)
35+
{
36+
if (collection->get_value(i)->compare(arguments.back()) == 0)
37+
instances++;
38+
}
39+
return gc->new_apartment(new value(VALUE_TYPE_NUMERICAL, new long double((long double)instances)));
2540
}

src/linq.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@
1010

1111
reference_apartment* allocate_array(std::list<value*> arguments, garbage_collector* gc);
1212
reference_apartment* get_length(std::list<value*> arguments, garbage_collector* gc);
13+
reference_apartment* count_instances(std::list<value*> arguments, garbage_collector* gc);
1314

1415
#endif // !LINQ_H

0 commit comments

Comments
 (0)