Archived
1
0
Fork 0

Added vectors into the syntax of the language

This commit is contained in:
Brandon Rozek 2018-10-01 17:15:59 -04:00
parent 034a97e3ab
commit cf0a90dda1
6 changed files with 71 additions and 6 deletions

View file

@ -3,6 +3,7 @@
#define STATEMENT 200
#define CALLFUNC 201
#define VECTOR 202
class Node;

View file

@ -46,6 +46,7 @@ std::string tree_string(const Node* node, uint tabs) {
switch(node->type) {
case IDENTIFIER: result += "IDENTIFIER: " + node->id + "\n"; break;
case VECTOR: result += "VECTOR:\n"; break;
case PLUS: result += "PLUS:\n"; break;
case MINUS: result += "MINUS:\n"; break;
case DIVIDE: result += "DIVIDE:\n"; break;
@ -81,6 +82,54 @@ std::string tree_string(const Node* node, uint tabs) {
return result;
}
Value* parse_vector(Node* node) {
// We will only support homogeneous vectors
// Get the first data type from the first node
Value* tempValue = new Value(*node->value);
TypeTag type = tempValue->type;
delete tempValue;
// Only numeric types and booleans are supported currently
if (type != LONG && type != BOOLEAN && type != DOUBLE) {
std::cerr << "Error, only numeric types and booleans are supported in vector form." << std::endl;
return make_false();
}
std::vector<long> longResult;
std::vector<double> doubleResult;
bool lastNode = false;
Node* currentNode = node;
do {
if (currentNode->value->type == type) {
tempValue = new Value(*currentNode->value);
if (type == LONG || type == BOOLEAN) {
std::vector<long> tempVec = get_long(tempValue);
delete tempValue;
longResult.insert(std::end(longResult), std::begin(tempVec), std::end(tempVec));
} else { // Assume Double
std::vector<double> tempVec = get_double(tempValue);
delete tempValue;
doubleResult.insert(std::end(doubleResult), std::begin(tempVec), std::end(tempVec));
}
} else { std::cerr << "Error, only homogenous arrays are supported." << std::endl; return make_false(); }
if (currentNode->num_children == 0) {
lastNode = true;
} else {
currentNode = currentNode->children[0];
}
} while (currentNode->num_children == 1 || !lastNode);
if (type == LONG || type == BOOLEAN) {
return make_long(longResult);
} else { // Assume double
return make_double(doubleResult);
}
}
Value* eval_expression(Node* node, Environment* env) {
/* base case */
if(!node) {
@ -112,6 +161,7 @@ Value* eval_expression(Node* node, Environment* env) {
switch(node->type) {
case LAMBDATAG: return make_expression(node); break;
case VECTOR: return parse_vector(node->children[0]); break;
case CALLFUNC:
check_num_nodes(node, 2, "cannot have more than two nodes for a function call.");
tempVal = get_value(find_variable(env, node->children[0]->id));

View file

@ -51,4 +51,6 @@ std::string tree_string(const Node* node, uint tabs);
void eval_statement(Node* node, Environment* env);
Value* eval_expression(Node* node, Environment* env);
Value* parse_vector(Node* node);
#endif

View file

@ -46,6 +46,7 @@ DIGIT [0-9]
"input" {return INPUT;}
"lambda" {return LAMBDATAG;}
":" {return COLON;}
"," {return COMMA;}
"true" {yylval.value = new Node(VALUE, std::unique_ptr<Value>(make_true()), ""); return VALUE;}
"false" {yylval.value = new Node(VALUE, std::unique_ptr<Value>(make_false()), ""); return VALUE;}
\".*\" {yylval.value = new Node(VALUE, std::unique_ptr<Value>(make_string(substring(yytext, 1, strlen(yytext) - 1))), ""); return VALUE; }

View file

@ -9,7 +9,7 @@
/* declare type possibilities of symbols */
%union {
struct Node* value;
Node* value;
}
/* declare tokens (default is typeless) */
@ -31,7 +31,9 @@
%token SEMICOLON
%token ASSIGN
%token OPENPAREM
%token ENDPAREM
%token ENDPAREM
%token OPENVECTOR
%token CLOSEVECTOR
%token BEGINTOK
%token END
%token IF
@ -46,9 +48,10 @@
%token DONE
%token <value> LAMBDATAG
%token COLON
%token COMMA
/* declare non-terminals */
%type <value> program statement assignment if-statement if-else-statement while print statements substatements callfunc exprlambda expression subexpression term subterm factor atom identvalue ident
%type <value> program statement assignment if-statement if-else-statement while print statements substatements callfunc vector vectorlist exprlambda expression subexpression term subterm factor atom identvalue ident
/* give us more detailed errors */
%error-verbose
@ -64,7 +67,7 @@ statement: assignment { $$ = $1; }
| print { $$ = $1; }
| statements { $$ = $1; }
assignment: ident ASSIGN exprlambda SEMICOLON {
assignment: ident ASSIGN vector SEMICOLON {
$$ = new Node(ASSIGN, NULL, "");
attach_node($$, $1);
attach_node($$, $3);
@ -89,7 +92,7 @@ while: WHILE expression DO statement {
attach_node($$, $4);
}
print: PRINT exprlambda SEMICOLON {
print: PRINT vector SEMICOLON {
$$ = new Node(PRINT, NULL, "");
attach_node($$, $2);
}
@ -101,6 +104,13 @@ statements: BEGINTOK substatements END { $$ = $2; }
substatements: statement substatements {$$ = new Node(STATEMENT, NULL, ""); attach_node($$, $1); attach_node($$, $2); }
| statement {$$ = new Node(STATEMENT, NULL, ""); attach_node($$, $1); }
vector: OPENVECTOR CLOSEVECTOR { $$ = new Node(VECTOR, std::unique_ptr<Value>(nullptr), ""); /*Empty vector*/ }
| OPENVECTOR vectorlist CLOSEVECTOR { $$ = new Node(VECTOR, std::unique_ptr<Value>(nullptr), ""); attach_node($$, $2); }
| exprlambda { $$ = $1; }
vectorlist: exprlambda COMMA vectorlist {$$ = $1; attach_node($$, $3); }
| exprlambda { $$ = $1; }
exprlambda: LAMBDATAG ident COLON expression {
// Only supports one argument functions for now
$$ = new Node(LAMBDATAG, NULL, "");
@ -143,6 +153,7 @@ ident: IDENTIFIER { $$ = $1; }
identvalue: ident { $$ = $1; }
| VALUE { $$ = $1; }
| INPUT { $$ = new Node(INPUT, NULL , ""); }
| OPENVECTOR identvalue CLOSEVECTOR { $$ = new Node(OPENVECTOR, NULL, ""); attach_node($$, $2); }

View file

@ -52,7 +52,7 @@ class Value {
// Destructor
~Value() {
std::cout << "VALUE DESTROYED" << std::endl;
// std::cout << "VALUE DESTROYED" << std::endl;
}
};