Added vectors into the syntax of the language
This commit is contained in:
parent
034a97e3ab
commit
cf0a90dda1
6 changed files with 71 additions and 6 deletions
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#define STATEMENT 200
|
#define STATEMENT 200
|
||||||
#define CALLFUNC 201
|
#define CALLFUNC 201
|
||||||
|
#define VECTOR 202
|
||||||
|
|
||||||
class Node;
|
class Node;
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ std::string tree_string(const Node* node, uint tabs) {
|
||||||
|
|
||||||
switch(node->type) {
|
switch(node->type) {
|
||||||
case IDENTIFIER: result += "IDENTIFIER: " + node->id + "\n"; break;
|
case IDENTIFIER: result += "IDENTIFIER: " + node->id + "\n"; break;
|
||||||
|
case VECTOR: result += "VECTOR:\n"; break;
|
||||||
case PLUS: result += "PLUS:\n"; break;
|
case PLUS: result += "PLUS:\n"; break;
|
||||||
case MINUS: result += "MINUS:\n"; break;
|
case MINUS: result += "MINUS:\n"; break;
|
||||||
case DIVIDE: result += "DIVIDE:\n"; break;
|
case DIVIDE: result += "DIVIDE:\n"; break;
|
||||||
|
@ -81,6 +82,54 @@ std::string tree_string(const Node* node, uint tabs) {
|
||||||
return result;
|
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) {
|
Value* eval_expression(Node* node, Environment* env) {
|
||||||
/* base case */
|
/* base case */
|
||||||
if(!node) {
|
if(!node) {
|
||||||
|
@ -112,6 +161,7 @@ Value* eval_expression(Node* node, Environment* env) {
|
||||||
|
|
||||||
switch(node->type) {
|
switch(node->type) {
|
||||||
case LAMBDATAG: return make_expression(node); break;
|
case LAMBDATAG: return make_expression(node); break;
|
||||||
|
case VECTOR: return parse_vector(node->children[0]); break;
|
||||||
case CALLFUNC:
|
case CALLFUNC:
|
||||||
check_num_nodes(node, 2, "cannot have more than two nodes for a function call.");
|
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));
|
tempVal = get_value(find_variable(env, node->children[0]->id));
|
||||||
|
|
|
@ -51,4 +51,6 @@ std::string tree_string(const Node* node, uint tabs);
|
||||||
void eval_statement(Node* node, Environment* env);
|
void eval_statement(Node* node, Environment* env);
|
||||||
Value* eval_expression(Node* node, Environment* env);
|
Value* eval_expression(Node* node, Environment* env);
|
||||||
|
|
||||||
|
Value* parse_vector(Node* node);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -46,6 +46,7 @@ DIGIT [0-9]
|
||||||
"input" {return INPUT;}
|
"input" {return INPUT;}
|
||||||
"lambda" {return LAMBDATAG;}
|
"lambda" {return LAMBDATAG;}
|
||||||
":" {return COLON;}
|
":" {return COLON;}
|
||||||
|
"," {return COMMA;}
|
||||||
"true" {yylval.value = new Node(VALUE, std::unique_ptr<Value>(make_true()), ""); return VALUE;}
|
"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;}
|
"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; }
|
\".*\" {yylval.value = new Node(VALUE, std::unique_ptr<Value>(make_string(substring(yytext, 1, strlen(yytext) - 1))), ""); return VALUE; }
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
/* declare type possibilities of symbols */
|
/* declare type possibilities of symbols */
|
||||||
%union {
|
%union {
|
||||||
struct Node* value;
|
Node* value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* declare tokens (default is typeless) */
|
/* declare tokens (default is typeless) */
|
||||||
|
@ -31,7 +31,9 @@
|
||||||
%token SEMICOLON
|
%token SEMICOLON
|
||||||
%token ASSIGN
|
%token ASSIGN
|
||||||
%token OPENPAREM
|
%token OPENPAREM
|
||||||
%token ENDPAREM
|
%token ENDPAREM
|
||||||
|
%token OPENVECTOR
|
||||||
|
%token CLOSEVECTOR
|
||||||
%token BEGINTOK
|
%token BEGINTOK
|
||||||
%token END
|
%token END
|
||||||
%token IF
|
%token IF
|
||||||
|
@ -46,9 +48,10 @@
|
||||||
%token DONE
|
%token DONE
|
||||||
%token <value> LAMBDATAG
|
%token <value> LAMBDATAG
|
||||||
%token COLON
|
%token COLON
|
||||||
|
%token COMMA
|
||||||
|
|
||||||
/* declare non-terminals */
|
/* 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 */
|
/* give us more detailed errors */
|
||||||
%error-verbose
|
%error-verbose
|
||||||
|
@ -64,7 +67,7 @@ statement: assignment { $$ = $1; }
|
||||||
| print { $$ = $1; }
|
| print { $$ = $1; }
|
||||||
| statements { $$ = $1; }
|
| statements { $$ = $1; }
|
||||||
|
|
||||||
assignment: ident ASSIGN exprlambda SEMICOLON {
|
assignment: ident ASSIGN vector SEMICOLON {
|
||||||
$$ = new Node(ASSIGN, NULL, "");
|
$$ = new Node(ASSIGN, NULL, "");
|
||||||
attach_node($$, $1);
|
attach_node($$, $1);
|
||||||
attach_node($$, $3);
|
attach_node($$, $3);
|
||||||
|
@ -89,7 +92,7 @@ while: WHILE expression DO statement {
|
||||||
attach_node($$, $4);
|
attach_node($$, $4);
|
||||||
}
|
}
|
||||||
|
|
||||||
print: PRINT exprlambda SEMICOLON {
|
print: PRINT vector SEMICOLON {
|
||||||
$$ = new Node(PRINT, NULL, "");
|
$$ = new Node(PRINT, NULL, "");
|
||||||
attach_node($$, $2);
|
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); }
|
substatements: statement substatements {$$ = new Node(STATEMENT, NULL, ""); attach_node($$, $1); attach_node($$, $2); }
|
||||||
| statement {$$ = new Node(STATEMENT, NULL, ""); attach_node($$, $1); }
|
| 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 {
|
exprlambda: LAMBDATAG ident COLON expression {
|
||||||
// Only supports one argument functions for now
|
// Only supports one argument functions for now
|
||||||
$$ = new Node(LAMBDATAG, NULL, "");
|
$$ = new Node(LAMBDATAG, NULL, "");
|
||||||
|
@ -143,6 +153,7 @@ ident: IDENTIFIER { $$ = $1; }
|
||||||
identvalue: ident { $$ = $1; }
|
identvalue: ident { $$ = $1; }
|
||||||
| VALUE { $$ = $1; }
|
| VALUE { $$ = $1; }
|
||||||
| INPUT { $$ = new Node(INPUT, NULL , ""); }
|
| INPUT { $$ = new Node(INPUT, NULL , ""); }
|
||||||
|
| OPENVECTOR identvalue CLOSEVECTOR { $$ = new Node(OPENVECTOR, NULL, ""); attach_node($$, $2); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ class Value {
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
~Value() {
|
~Value() {
|
||||||
std::cout << "VALUE DESTROYED" << std::endl;
|
// std::cout << "VALUE DESTROYED" << std::endl;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Reference in a new issue