This server is intended for use for Academic Classwork related Git repositories only. Projects/repositories will generally be removed after 6 months following close of the semester. Inactive repositories from previous semester are now being archived when no activity for 365 days. They are renamed and marked as 'archived'. After 90 days in that state they will be removed from the system completely.

Commit b1223c46 authored by Jonathan Evans's avatar Jonathan Evans

added arithlogic functionality

parent 8c14b75d
......@@ -2,6 +2,7 @@
#define SYMBOL_TABLE_ENTRY_H
#include <string>
#include <cstring>
#include <ostream>
#include <stdexcept>
using namespace std;
......@@ -21,6 +22,20 @@ using namespace std;
#define LOGICAL 11
#define RELATIONAL 12
#define ADD 0
#define SUBTRACT 1
#define MULTIPLY 2
#define DIVIDE 3
#define AND 4
#define OR 5
#define NOT 6
#define LT 7
#define GT 8
#define LE 9
#define GE 10
#define EQ 11
#define NE 12
union TYPE_VALUE{
char* text;
bool boolean;
......@@ -40,6 +55,67 @@ struct TYPE_INFO
// operatorType is only applicable if production is an operator
int operatorType;
int operatorInstance;
operator bool(){
if(type == BOOL){
return value.boolean;
}
return true;
}
bool operator!(){
return !(*this);
}
// man I really wish I had c++20's operator<=>/operator semantics right now
bool operator<(const TYPE_INFO& rhs) {
if(type != rhs.type){
throw std::invalid_argument("invalid type for comparison");
}
bool result = false;
switch(rhs.type){
case INT:
result = value.number < rhs.value.number;
break;
case STR:
result = (strcmp(value.text, rhs.value.text) == -1);
break;
}
return result;
}
bool operator==(const TYPE_INFO& rhs){
if(type != rhs.type){
throw std::invalid_argument("invalid type for comparison");
}
bool result = false;
switch(rhs.type){
case INT:
result = value.number == rhs.value.number;
break;
case STR:
result = (strcmp(value.text, rhs.value.text) == 0);
break;
}
return result;
}
bool operator<=(const TYPE_INFO& rhs){
return (*this < rhs) || (*this == rhs);
}
bool operator>=(const TYPE_INFO& rhs){
return !(*this < rhs);
}
bool operator>(const TYPE_INFO& rhs){
return !(*this <= rhs);
}
bool operator!=(const TYPE_INFO& rhs){
return !(*this == rhs);
}
friend ostream& operator<<(ostream& os, const TYPE_INFO& rhs){
switch(rhs.type){
......
......@@ -137,14 +137,16 @@ COMMENT ";".*
}
{INTCONST} {
yylval.number = atoi(yytext);
return T_INTCONST;
}
{STRCONST} {
yylval.text = strdup(yytext);
return T_STRCONST;
}
{NEWLINE} {
{NEWLINE} {
numLines++;
}
......
......@@ -37,6 +37,7 @@ extern "C"
%union
{
char* text;
int number;
TYPE_INFO typeInfo;
};
......@@ -53,6 +54,8 @@ extern "C"
* Type Identifications
*/
%type <text> T_IDENT
%type <text> T_STRCONST
%type <number> T_INTCONST
%type <typeInfo> N_START N_EXPR N_CONST N_PARENTHESIZED_EXPR
%type <typeInfo> N_PROGN_OR_USERFUNCTCALL N_ACTUAL_PARAMS N_FUNCT_NAME
%type <typeInfo> N_ARITHLOGIC_EXPR N_IF_EXPR N_LET_EXPR N_ID_EXPR_LIST
......@@ -125,24 +128,28 @@ N_EXPR : N_CONST
}
//resulting type is the type of the identifier
//look up in the symbol table
$$.type = getEntryInAnyScope(lexeme).getTypeInfo().type;
TYPE_INFO entryInfo = getEntryInAnyScope(lexeme).getTypeInfo();
$$.type = entryInfo.type;
$$.value = entryInfo.value;
}
| T_LPAREN N_PARENTHESIZED_EXPR T_RPAREN
{
//resulting value is the value of the N_PARENTHESIZED_EXPR
//resulting type is the resulting type of the parenthesized expr
$$.type=$2.type;
$$.numParams=$2.numParams;
$$.returnType=$2.returnType;
$$.type = $2.type;
$$.numParams = $2.numParams;
$$.returnType = $2.returnType;
$$.value = $2.value;
}
;
N_CONST : T_INTCONST
{
//value is the value of the T_INTCONST
//type is int
$$.type=INT;
$$.numParams=NOT_APPLICABLE;
$$.returnType=NOT_APPLICABLE;
$$.type = INT;
$$.numParams = NOT_APPLICABLE;
$$.returnType = NOT_APPLICABLE;
$$.value.number = $1;
}
| T_STRCONST
{
......@@ -151,6 +158,7 @@ N_CONST : T_INTCONST
$$.type=STR;
$$.numParams=NOT_APPLICABLE;
$$.returnType=NOT_APPLICABLE;
$$.value.text = $1;
}
| T_T
{
......@@ -159,6 +167,7 @@ N_CONST : T_INTCONST
$$.type=BOOL;
$$.numParams=NOT_APPLICABLE;
$$.returnType=NOT_APPLICABLE;
$$.value.boolean = true;
}
| T_NIL
{
......@@ -167,6 +176,7 @@ N_CONST : T_INTCONST
$$.type=BOOL;
$$.numParams=NOT_APPLICABLE;
$$.returnType=NOT_APPLICABLE;
$$.value.boolean = false;
}
;
N_PARENTHESIZED_EXPR : N_ARITHLOGIC_EXPR
......@@ -177,36 +187,42 @@ N_PARENTHESIZED_EXPR : N_ARITHLOGIC_EXPR
$$.type=$1.type;
$$.numParams=$1.numParams;
$$.returnType=$1.returnType;
$$.value=$1.value;
}
| N_IF_EXPR
{
$$.type=$1.type;
$$.numParams=$1.numParams;
$$.returnType=$1.returnType;
$$.value=$1.value;
}
| N_LET_EXPR
{
$$.type=$1.type;
$$.numParams=$1.numParams;
$$.returnType=$1.returnType;
$$.value=$1.value;
}
| N_PRINT_EXPR
{
$$.type=$1.type;
$$.numParams=$1.numParams;
$$.returnType=$1.returnType;
$$.value=$1.value;
}
| N_INPUT_EXPR
{
$$.type=$1.type;
$$.numParams=$1.numParams;
$$.returnType=$1.returnType;
$$.value=$1.value;
}
| N_PROGN_OR_USERFUNCTCALL
{
$$.type=$1.type;
$$.numParams=$1.numParams;
$$.returnType=$1.returnType;
$$.value=$1.value;
}
| T_EXIT
{
......@@ -233,6 +249,7 @@ N_PROGN_OR_USERFUNCTCALL : N_FUNCT_NAME N_ACTUAL_PARAMS
$$.numParams = $2.numParams;
$$.returnType = UNDEFINED;
$$.value = $2.value;
}
;
N_ACTUAL_PARAMS : N_EXPR_LIST
......@@ -240,6 +257,7 @@ N_ACTUAL_PARAMS : N_EXPR_LIST
$$.type = $1.type;
$$.numParams = $1.numParams;
$$.returnType = $1.type;
$$.value = $1.value;
}
| /*epsilon*/
{
......@@ -279,6 +297,12 @@ N_ARITHLOGIC_EXPR : N_UN_OP N_EXPR
$$.type = BOOL;
$$.numParams = NOT_APPLICABLE;
$$.returnType = NOT_APPLICABLE;
//Slightly redundant, but good in the event of future expansion
switch($1.operatorInstance){
case NOT:
$$.value.boolean = !$2;
break;
}
}
| N_BIN_OP N_EXPR N_EXPR
{
......@@ -301,6 +325,27 @@ N_ARITHLOGIC_EXPR : N_UN_OP N_EXPR
yyerror("Arg 2 must be string");
}
switch($1.operatorInstance){
case LT:
$$.value.boolean = ($2 < $3);
break;
case GT:
$$.value.boolean = ($2 > $3);
break;
case LE:
$$.value.boolean = ($2 <= $3);
break;
case GE:
$$.value.boolean = ($2 >= $3);
break;
case EQ:
$$.value.boolean = ($2 == $3);
break;
case NE:
$$.value.boolean = ($2 != $3);
break;
}
break;
case LOGICAL:
if($2.type == FUNCTION) {
......@@ -311,6 +356,15 @@ N_ARITHLOGIC_EXPR : N_UN_OP N_EXPR
yyerror("Arg 2 cannot be a function");
}
switch($1.operatorInstance){
case AND:
$$.value.boolean = (($2) && ($3));
break;
case OR:
$$.value.boolean = (($2) || ($3));
break;
}
break;
case ARITHMETIC:
switch($2.type){
......@@ -335,6 +389,21 @@ N_ARITHLOGIC_EXPR : N_UN_OP N_EXPR
break;
}
switch($1.operatorInstance){
case ADD:
$$.value.number = $2.value.number + $3.value.number;
break;
case SUBTRACT:
$$.value.number = $2.value.number - $3.value.number;
break;
case MULTIPLY:
$$.value.number = $2.value.number * $3.value.number;
break;
case DIVIDE:
$$.value.number = $2.value.number / $3.value.number;
break;
}
break;
}
......@@ -428,6 +497,7 @@ N_BIN_OP : N_ARITH_OP
$$.numParams = NOT_APPLICABLE;
$$.returnType = NOT_APPLICABLE;
$$.operatorType = ARITHMETIC;
$$.operatorInstance = $1.operatorInstance;
}
| N_LOG_OP
{
......@@ -435,6 +505,7 @@ N_BIN_OP : N_ARITH_OP
$$.numParams = NOT_APPLICABLE;
$$.returnType = NOT_APPLICABLE;
$$.operatorType = LOGICAL;
$$.operatorInstance = $1.operatorInstance;
}
| N_REL_OP
{
......@@ -442,49 +513,63 @@ N_BIN_OP : N_ARITH_OP
$$.numParams = NOT_APPLICABLE;
$$.returnType = NOT_APPLICABLE;
$$.operatorType = RELATIONAL;
$$.operatorInstance = $1.operatorInstance;
}
;
N_ARITH_OP : T_ADD
{
$$.operatorInstance = ADD;
}
| T_SUB
{
$$.operatorInstance = SUBTRACT;
}
| T_MULT
{
$$.operatorInstance = MULTIPLY;
}
| T_DIV
{
$$.operatorInstance = DIVIDE;
}
;
N_REL_OP : T_LT
{
$$.operatorInstance = LT;
}
| T_GT
{
$$.operatorInstance = GT;
}
| T_LE
{
$$.operatorInstance = LE;
}
| T_GE
{
$$.operatorInstance = GE;
}
| T_EQ
{
$$.operatorInstance = EQ;
}
| T_NE
{
$$.operatorInstance = NE;
}
;
N_LOG_OP : T_AND
{
$$.operatorInstance = AND;
}
| T_OR
{
$$.operatorInstance = OR;
}
;
N_UN_OP : T_NOT
{
$$.operatorInstance = NOT;
}
;
%%
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment