Archived
1
0
Fork 0

Added string support to SLOTH (comparisons, string concatenation, etc)

Refactored print_value code
This commit is contained in:
Brandon Rozek 2018-09-26 15:43:08 -04:00
parent 1186419184
commit 28e2352eac
10 changed files with 135 additions and 36 deletions

1
.gitignore vendored
View file

@ -9,6 +9,7 @@ src/variables/value.o
src/operations/node.o src/operations/node.o
src/operations/operators.o src/operations/operators.o
src/shell.o src/shell.o
src/string.o
sloth sloth
vgcore* vgcore*
.vscode .vscode

View file

@ -1,5 +1,5 @@
sloth: src/main.c src/parser/lex.yy.o src/parser/parser.tab.o src/variables/environment.o src/variables/variable.o src/variables/value.o src/operations/node.o src/operations/operators.o src/shell.o sloth: src/main.c src/parser/lex.yy.o src/parser/parser.tab.o src/variables/environment.o src/variables/variable.o src/variables/value.o src/operations/node.o src/operations/operators.o src/string.o src/shell.o
gcc src/main.c src/parser/lex.yy.o src/parser/parser.tab.o src/variables/environment.o src/variables/variable.o src/variables/value.o src/operations/node.o src/operations/operators.o src/shell.o -ledit -o sloth gcc src/main.c src/parser/lex.yy.o src/parser/parser.tab.o src/variables/environment.o src/variables/variable.o src/variables/value.o src/operations/node.o src/operations/operators.o src/string.o src/shell.o -ledit -o sloth
src/parser/lex.yy.o: src/parser/lex.yy.c src/parser/parser.tab.h src/parser/lex.yy.o: src/parser/lex.yy.c src/parser/parser.tab.h
gcc -c src/parser/lex.yy.c -o src/parser/lex.yy.o gcc -c src/parser/lex.yy.c -o src/parser/lex.yy.o
src/parser/parser.tab.o: src/parser/parser.tab.c src/parser/parser.tab.o: src/parser/parser.tab.c
@ -22,5 +22,7 @@ src/operations/node.o: src/operations/node.h src/operations/node.c
gcc -c src/operations/node.c -o src/operations/node.o gcc -c src/operations/node.c -o src/operations/node.o
src/shell.o: src/shell.h src/shell.c src/shell.o: src/shell.h src/shell.c
gcc -c src/shell.c -o src/shell.o gcc -c src/shell.c -o src/shell.o
src/string.o: src/string.h src/string.c
gcc -c src/string.c -o src/string.o
clean: clean:
rm src/parser/lex.yy.c src/parser/parser.tab.c src/parser/parser.tab.h src/parser/lex.yy.o src/parser/parser.tab.o src/variables/environment.o src/variables/variable.o src/variables/value.o src/operations/node.o src/operations/operators.o src/shell.o sloth rm src/parser/lex.yy.c src/parser/parser.tab.c src/parser/parser.tab.h src/parser/lex.yy.o src/parser/parser.tab.o src/variables/environment.o src/variables/variable.o src/variables/value.o src/operations/node.o src/operations/operators.o src/shell.o sloth

View file

@ -34,7 +34,7 @@ void interpret_file(char* fileName) {
stdin = orig_stdin; stdin = orig_stdin;
// Interpret the AST // Interpret the AST
// print_tree(result, 0); // print_tree(result, 0); // For debugging
struct Environment* env = create_environment(); struct Environment* env = create_environment();
eval_statement(result, env); eval_statement(result, env);
delete_environment(env); delete_environment(env);

View file

@ -80,17 +80,9 @@ void print_tree(struct Node* node, int tabs) {
case CALLFUNC: printf("FUNCTIONCALL:\n"); break; case CALLFUNC: printf("FUNCTIONCALL:\n"); break;
case STATEMENT: printf("STATEMENT:\n"); break; case STATEMENT: printf("STATEMENT:\n"); break;
case VALUE: case VALUE:
if (node->value->type == BOOLEAN) { printf("VALUE: ");
if (get_long(node->value)) { print_value(node->value);
printf("VALUE: true\n"); printf("\n");
} else {
printf("VALUE: false\n");
}
} else if (node->value->type == LONG) {
printf("VALUE: %li\n", get_long(node->value));
} else { // Assume double
printf("VALUE: %lf\n", get_double(node->value));
}
break; break;
default: default:
printf("Error, %d not a valid node type.\n", node->type); printf("Error, %d not a valid node type.\n", node->type);
@ -311,19 +303,8 @@ void eval_statement(struct Node* node, struct Environment* env) {
case PRINT: case PRINT:
check_num_nodes(node, 1, "can only print out one expression at a time."); check_num_nodes(node, 1, "can only print out one expression at a time.");
tempVal = eval_expression(node->children[0], env); tempVal = eval_expression(node->children[0], env);
if (tempVal->type == BOOLEAN) { print_value(tempVal);
if (get_long(tempVal)) { printf("\n");
printf("true\n");
} else {
printf("false\n");
}
} else if (tempVal->type == LONG) {
printf("%li\n", get_long(tempVal));
} else if (tempVal ->type == DOUBLE) {
printf("%lf\n", get_double(tempVal));
} else { // Assume lambda expression
printf("<LambdaExpression>\n");
}
break; break;
//------------ //------------
case STATEMENT: // Can have a maximum of two children statement nodes case STATEMENT: // Can have a maximum of two children statement nodes

View file

@ -1,11 +1,15 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include "operators.h" #include "operators.h"
#include "../variables/value.h" #include "../variables/value.h"
struct Value* add(struct Value* x, struct Value* y) { struct Value* add(struct Value* x, struct Value* y) {
if (!x || !y) { fprintf(stderr, "Error, uninitialized values being used in add.\n"); } if (!x || !y) { fprintf(stderr, "Error, uninitialized values being used in add.\n"); }
if (x->type == BOOLEAN || y->type == BOOLEAN) { fprintf(stderr, "Error, cannot add a boolean.\n"); } if (x->type == BOOLEAN || y->type == BOOLEAN) { fprintf(stderr, "Error, cannot add a boolean.\n"); }
if ((x->type == STRING || y->type == STRING) && (x->type != STRING || y->type != STRING)) {
fprintf(stderr, "Error, cannot add a string with another data type.\n");
}
struct Value* ans; struct Value* ans;
@ -16,6 +20,8 @@ struct Value* add(struct Value* x, struct Value* y) {
ans = make_double(get_long(x) + get_double(y)); ans = make_double(get_long(x) + get_double(y));
} else if (x->type == DOUBLE && y->type == LONG) { } else if (x->type == DOUBLE && y->type == LONG) {
ans = make_double(get_double(x) + get_long(y)); ans = make_double(get_double(x) + get_long(y));
} else if (x->type == STRING && y->type == STRING) {
ans = make_string(strcat(get_string(x), get_string(y)));
} else { // Both are DOUBLE } else { // Both are DOUBLE
ans = make_double(get_double(x) + get_double(y)); ans = make_double(get_double(x) + get_double(y));
} }
@ -26,6 +32,7 @@ struct Value* add(struct Value* x, struct Value* y) {
struct Value* subtract(struct Value* x, struct Value* y) { struct Value* subtract(struct Value* x, struct Value* y) {
if (!x || !y) { fprintf(stderr, "Error, uninitialized values being used in subtract.\n"); } if (!x || !y) { fprintf(stderr, "Error, uninitialized values being used in subtract.\n"); }
if (x->type == BOOLEAN || y->type == BOOLEAN) { fprintf(stderr, "Error, cannot subtract a boolean.\n"); } if (x->type == BOOLEAN || y->type == BOOLEAN) { fprintf(stderr, "Error, cannot subtract a boolean.\n"); }
if (x->type == STRING || y->type == STRING) { fprintf(stderr, "Error, cannot subtract a string.\n"); }
struct Value* ans; struct Value* ans;
@ -46,6 +53,7 @@ struct Value* subtract(struct Value* x, struct Value* y) {
struct Value* division(struct Value* x, struct Value* y) { struct Value* division(struct Value* x, struct Value* y) {
if (!x || !y) { fprintf(stderr, "Error, uninitialized values being used in divide.\n"); } if (!x || !y) { fprintf(stderr, "Error, uninitialized values being used in divide.\n"); }
if (x->type == BOOLEAN || y->type == BOOLEAN) { fprintf(stderr, "Error, cannot divide a boolean.\n"); } if (x->type == BOOLEAN || y->type == BOOLEAN) { fprintf(stderr, "Error, cannot divide a boolean.\n"); }
if (x->type == STRING || y->type == STRING) { fprintf(stderr, "Error, cannot division a string.\n"); }
struct Value* ans; struct Value* ans;
@ -66,6 +74,7 @@ struct Value* division(struct Value* x, struct Value* y) {
struct Value* multiplication(struct Value* x, struct Value* y) { struct Value* multiplication(struct Value* x, struct Value* y) {
if (!x || !y) { fprintf(stderr, "Error, uninitialized values being used in multiply.\n"); } if (!x || !y) { fprintf(stderr, "Error, uninitialized values being used in multiply.\n"); }
if (x->type == BOOLEAN || y->type == BOOLEAN) { fprintf(stderr, "Error, cannot multiply a boolean.\n"); } if (x->type == BOOLEAN || y->type == BOOLEAN) { fprintf(stderr, "Error, cannot multiply a boolean.\n"); }
if (x->type == STRING || y->type == STRING) { fprintf(stderr, "Error, cannot multiply a string.\n"); }
struct Value* ans; struct Value* ans;
@ -86,6 +95,9 @@ struct Value* multiplication(struct Value* x, struct Value* y) {
struct Value* less(struct Value* x, struct Value* y) { struct Value* less(struct Value* x, struct Value* y) {
if (!x || !y) { fprintf(stderr, "Error, uninitialized values being used in <.\n"); } if (!x || !y) { fprintf(stderr, "Error, uninitialized values being used in <.\n"); }
if (x->type == BOOLEAN || y->type == BOOLEAN) { fprintf(stderr, "Error, cannot numerically compare a boolean.\n"); } if (x->type == BOOLEAN || y->type == BOOLEAN) { fprintf(stderr, "Error, cannot numerically compare a boolean.\n"); }
if ((x->type == STRING || y->type == STRING) && (x->type != STRING || y->type != STRING)) {
fprintf(stderr, "Error, cannot compare a string with another data type.\n");
}
struct Value* ans; struct Value* ans;
@ -96,6 +108,8 @@ struct Value* less(struct Value* x, struct Value* y) {
ans = make_boolean(get_long(x) < get_double(y)); ans = make_boolean(get_long(x) < get_double(y));
} else if (x->type == DOUBLE && y->type == LONG) { } else if (x->type == DOUBLE && y->type == LONG) {
ans = make_boolean(get_double(x) < get_long(y)); ans = make_boolean(get_double(x) < get_long(y));
} else if (x->type == STRING && y->type == STRING) {
ans = make_boolean(strcmp(get_string(x), get_string(y)) < 0);
} else { // Both are DOUBLE } else { // Both are DOUBLE
ans = make_boolean(get_double(x) < get_double(y)); ans = make_boolean(get_double(x) < get_double(y));
} }
@ -106,6 +120,9 @@ struct Value* less(struct Value* x, struct Value* y) {
struct Value* greater(struct Value* x, struct Value* y) { struct Value* greater(struct Value* x, struct Value* y) {
if (!x || !y) { fprintf(stderr, "Error, uninitialized values being used in greater.\n"); } if (!x || !y) { fprintf(stderr, "Error, uninitialized values being used in greater.\n"); }
if (x->type == BOOLEAN || y->type == BOOLEAN) { fprintf(stderr, "Error, cannot numerically compare a boolean.\n"); } if (x->type == BOOLEAN || y->type == BOOLEAN) { fprintf(stderr, "Error, cannot numerically compare a boolean.\n"); }
if ((x->type == STRING || y->type == STRING) && (x->type != STRING || y->type != STRING)) {
fprintf(stderr, "Error, cannot compare a string with another data type.\n");
}
struct Value* ans; struct Value* ans;
@ -116,6 +133,8 @@ struct Value* greater(struct Value* x, struct Value* y) {
ans = make_boolean(get_long(x) > get_double(y)); ans = make_boolean(get_long(x) > get_double(y));
} else if (x->type == DOUBLE && y->type == LONG) { } else if (x->type == DOUBLE && y->type == LONG) {
ans = make_boolean(get_double(x) > get_long(y)); ans = make_boolean(get_double(x) > get_long(y));
} else if (x->type == STRING && y->type == STRING) {
ans = make_boolean(strcmp(get_string(x), get_string(y)) > 0);
} else { // Both are DOUBLE } else { // Both are DOUBLE
ans = make_boolean(get_double(x) > get_double(y)); ans = make_boolean(get_double(x) > get_double(y));
} }
@ -126,6 +145,9 @@ struct Value* greater(struct Value* x, struct Value* y) {
struct Value* less_equal(struct Value* x, struct Value* y) { struct Value* less_equal(struct Value* x, struct Value* y) {
if (!x || !y) { fprintf(stderr, "Error, uninitialized values being used in <=.\n"); } if (!x || !y) { fprintf(stderr, "Error, uninitialized values being used in <=.\n"); }
if (x->type == BOOLEAN || y->type == BOOLEAN) { fprintf(stderr, "Error, cannot numerically compare a boolean.\n"); } if (x->type == BOOLEAN || y->type == BOOLEAN) { fprintf(stderr, "Error, cannot numerically compare a boolean.\n"); }
if ((x->type == STRING || y->type == STRING) && (x->type != STRING || y->type != STRING)) {
fprintf(stderr, "Error, cannot compare a string with another data type.\n");
}
struct Value* ans; struct Value* ans;
@ -136,6 +158,8 @@ struct Value* less_equal(struct Value* x, struct Value* y) {
ans = make_boolean(get_long(x) <= get_double(y)); ans = make_boolean(get_long(x) <= get_double(y));
} else if (x->type == DOUBLE && y->type == LONG) { } else if (x->type == DOUBLE && y->type == LONG) {
ans = make_boolean(get_double(x) <= get_long(y)); ans = make_boolean(get_double(x) <= get_long(y));
} else if (x->type == STRING && y->type == STRING) {
ans = make_boolean(strcmp(get_string(x), get_string(y)) <= 0);
} else { // Both are DOUBLE } else { // Both are DOUBLE
ans = make_boolean(get_double(x) <= get_double(y)); ans = make_boolean(get_double(x) <= get_double(y));
} }
@ -146,6 +170,9 @@ struct Value* less_equal(struct Value* x, struct Value* y) {
struct Value* greater_equal(struct Value* x, struct Value* y) { struct Value* greater_equal(struct Value* x, struct Value* y) {
if (!x || !y) { fprintf(stderr, "Error, uninitialized values being used in >=.\n"); } if (!x || !y) { fprintf(stderr, "Error, uninitialized values being used in >=.\n"); }
if (x->type == BOOLEAN || y->type == BOOLEAN) { fprintf(stderr, "Error, cannot numerically compare a boolean.\n"); } if (x->type == BOOLEAN || y->type == BOOLEAN) { fprintf(stderr, "Error, cannot numerically compare a boolean.\n"); }
if ((x->type == STRING || y->type == STRING) && (x->type != STRING || y->type != STRING)) {
fprintf(stderr, "Error, cannot compare a string with another data type.\n");
}
struct Value* ans; struct Value* ans;
@ -156,6 +183,8 @@ struct Value* greater_equal(struct Value* x, struct Value* y) {
ans = make_boolean(get_long(x) >= get_double(y)); ans = make_boolean(get_long(x) >= get_double(y));
} else if (x->type == DOUBLE && y->type == LONG) { } else if (x->type == DOUBLE && y->type == LONG) {
ans = make_boolean(get_double(x) >= get_long(y)); ans = make_boolean(get_double(x) >= get_long(y));
} else if (x->type == STRING && y->type == STRING) {
ans = make_boolean(strcmp(get_string(x), get_string(y)) >= 0);
} else { // Both are DOUBLE } else { // Both are DOUBLE
ans = make_boolean(get_double(x) >= get_double(y)); ans = make_boolean(get_double(x) >= get_double(y));
} }
@ -165,6 +194,9 @@ struct Value* greater_equal(struct Value* x, struct Value* y) {
struct Value* equals(struct Value* x, struct Value* y) { struct Value* equals(struct Value* x, struct Value* y) {
if (!x || !y) { fprintf(stderr, "Error, uninitialized values being used in ==.\n"); } if (!x || !y) { fprintf(stderr, "Error, uninitialized values being used in ==.\n"); }
if ((x->type == STRING || y->type == STRING) && (x->type != STRING || y->type != STRING)) {
fprintf(stderr, "Error, cannot compare a string with another data type.\n");
}
struct Value* ans; struct Value* ans;
@ -179,6 +211,8 @@ struct Value* equals(struct Value* x, struct Value* y) {
ans = make_boolean(get_double(x) == get_double(y)); ans = make_boolean(get_double(x) == get_double(y));
} else if (x->type == BOOLEAN && y->type == BOOLEAN) { } else if (x->type == BOOLEAN && y->type == BOOLEAN) {
ans = make_boolean(get_long(x) == get_long(y)); ans = make_boolean(get_long(x) == get_long(y));
} else if (x->type == STRING && y->type == STRING) {
ans = make_boolean(strcmp(get_string(x), get_string(y)) == 0);
} else { // Type is a mix between boolean and another type } else { // Type is a mix between boolean and another type
fprintf(stderr, "Error, cannot compare a boolean with another type.\n"); fprintf(stderr, "Error, cannot compare a boolean with another type.\n");
} }
@ -188,6 +222,9 @@ struct Value* equals(struct Value* x, struct Value* y) {
struct Value* not_equals(struct Value* x, struct Value* y) { struct Value* not_equals(struct Value* x, struct Value* y) {
if (!x || !y) { fprintf(stderr, "Error, uninitialized values being used in !=.\n"); } if (!x || !y) { fprintf(stderr, "Error, uninitialized values being used in !=.\n"); }
if ((x->type == STRING || y->type == STRING) && (x->type != STRING || y->type != STRING)) {
fprintf(stderr, "Error, cannot compare a string with another data type.\n");
}
struct Value* ans; struct Value* ans;
@ -202,6 +239,8 @@ struct Value* not_equals(struct Value* x, struct Value* y) {
ans = make_boolean(get_double(x) != get_double(y)); ans = make_boolean(get_double(x) != get_double(y));
} else if (x->type == BOOLEAN && y->type == BOOLEAN) { } else if (x->type == BOOLEAN && y->type == BOOLEAN) {
ans = make_boolean(get_long(x) != get_long(y)); ans = make_boolean(get_long(x) != get_long(y));
} else if (x->type == STRING && y->type == STRING) {
ans = make_boolean(strcmp(get_string(x), get_string(y)) != 0);
} else { // Type is a mix between boolean and another type } else { // Type is a mix between boolean and another type
fprintf(stderr, "Error, cannot compare a boolean with another type.\n"); fprintf(stderr, "Error, cannot compare a boolean with another type.\n");
} }
@ -212,6 +251,7 @@ struct Value* not_equals(struct Value* x, struct Value* y) {
struct Value* and(struct Value* x, struct Value* y) { struct Value* and(struct Value* x, struct Value* y) {
if (!x || !y) { fprintf(stderr, "Error, uninitialized values being used in &&.\n"); } if (!x || !y) { fprintf(stderr, "Error, uninitialized values being used in &&.\n"); }
if (x->type != BOOLEAN || y->type != BOOLEAN) { fprintf(stderr, "Error, cannot use and AND operation with a non-boolean.\n"); } if (x->type != BOOLEAN || y->type != BOOLEAN) { fprintf(stderr, "Error, cannot use and AND operation with a non-boolean.\n"); }
if (x->type == STRING || y->type == STRING) { fprintf(stderr, "Error, cannot AND a string.\n"); }
return make_boolean(get_long(x) && get_long(y)); return make_boolean(get_long(x) && get_long(y));
} }
@ -219,6 +259,7 @@ struct Value* and(struct Value* x, struct Value* y) {
struct Value* or(struct Value* x, struct Value* y) { struct Value* or(struct Value* x, struct Value* y) {
if (!x || !y) { fprintf(stderr, "Error, uninitialized values being used in ||.\n"); } if (!x || !y) { fprintf(stderr, "Error, uninitialized values being used in ||.\n"); }
if (x->type != BOOLEAN || y->type != BOOLEAN) { fprintf(stderr, "Error, cannot use and OR operation with a non-boolean.\n"); } if (x->type != BOOLEAN || y->type != BOOLEAN) { fprintf(stderr, "Error, cannot use and OR operation with a non-boolean.\n"); }
if (x->type == STRING || y->type == STRING) { fprintf(stderr, "Error, cannot OR a string.\n"); }
return make_boolean(get_long(x) || get_long(y)); return make_boolean(get_long(x) || get_long(y));
} }
@ -226,6 +267,7 @@ struct Value* or(struct Value* x, struct Value* y) {
struct Value* not(struct Value* x) { struct Value* not(struct Value* x) {
if (!x) { fprintf(stderr, "Error, uninitialized values being used in !.\n"); } if (!x) { fprintf(stderr, "Error, uninitialized values being used in !.\n"); }
if (x->type != BOOLEAN) { fprintf(stderr, "Error, cannot NOT a non-boolean.\n"); } if (x->type != BOOLEAN) { fprintf(stderr, "Error, cannot NOT a non-boolean.\n"); }
if (x->type == STRING) { fprintf(stderr, "Error, cannot negate a string.\n"); }
return make_boolean(!get_long(x)); return make_boolean(!get_long(x));
} }

View file

@ -4,6 +4,7 @@
#include "../operations/node.h" #include "../operations/node.h"
#include "../variables/value.h" #include "../variables/value.h"
#include "parser.tab.h" #include "parser.tab.h"
#include "../string.h"
/* Keep track of line numbers for error reporting */ /* Keep track of line numbers for error reporting */
int linenum = 0; int linenum = 0;
@ -44,6 +45,7 @@ DIGIT [0-9]
":" {return COLON;} ":" {return COLON;}
"true" {yylval.value = make_node(VALUE, make_true(), ""); return VALUE;} "true" {yylval.value = make_node(VALUE, make_true(), ""); return VALUE;}
"false" {yylval.value = make_node(VALUE, make_false(), ""); return VALUE;} "false" {yylval.value = make_node(VALUE, make_false(), ""); return VALUE;}
\".*\" {yylval.value = make_node(VALUE, make_string(substring(yytext, 1, strlen(yytext) - 1)), ""); return VALUE; }
{DIGIT} {yylval.value = make_node(VALUE, make_long(atoi(yytext)), ""); return VALUE;} {DIGIT} {yylval.value = make_node(VALUE, make_long(atoi(yytext)), ""); return VALUE;}
{DIGIT}*"."?{DIGIT}+ {yylval.value = make_node(VALUE, make_double(atof(yytext)), ""); return VALUE;} {DIGIT}*"."?{DIGIT}+ {yylval.value = make_node(VALUE, make_double(atof(yytext)), ""); return VALUE;}
[_a-zA-Z][_a-zA-Z0-9]* {yylval.value = make_node(IDENTIFIER, NULL, strdup(yytext)); return IDENTIFIER;} [_a-zA-Z][_a-zA-Z0-9]* {yylval.value = make_node(IDENTIFIER, NULL, strdup(yytext)); return IDENTIFIER;}

28
src/string.c Normal file
View file

@ -0,0 +1,28 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "string.h"
char* substring(char* str, int start, int end) {
// Add conditions that substring is valid, probably using strlen
int stringLength = strlen(str);
if (start >= stringLength || end > stringLength) { fprintf(stderr, "Requesting substring outside of valid range.\n"); return NULL; }
char* substr;
int c;
int length = end - start;
substr = malloc(length + 1);
if (substr == NULL) {
fprintf(stderr, "Unable to allocate memory for substring.\n");
exit(1);
}
for (c = 0; c < length; c++) {
substr[c] = str[start + c];
}
substr[c] = '\0';
return substr;
}

6
src/string.h Normal file
View file

@ -0,0 +1,6 @@
#ifndef STRING_H
#define STRING_H
char* substring(char* str, int start, int end);
#endif

View file

@ -1,9 +1,10 @@
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "value.h" #include "value.h"
#include "../parser/parser.tab.h" #include "../parser/parser.tab.h"
struct Value* make_value(int type, long num, double dec, struct Node* expr) { struct Value* make_value(int type, long num, double dec, struct Node* expr, char* str) {
/* allocate space */ /* allocate space */
struct Value* val = malloc(sizeof(struct Value)); struct Value* val = malloc(sizeof(struct Value));
@ -13,6 +14,8 @@ struct Value* make_value(int type, long num, double dec, struct Node* expr) {
val->value.num = num; val->value.num = num;
} else if (type == DOUBLE){ // Assume DOUBLE } else if (type == DOUBLE){ // Assume DOUBLE
val->value.dec = dec; val->value.dec = dec;
} else if (type == STRING) {
val->value.str = str;
} else { // Assume lambda expression } else { // Assume lambda expression
val->value.expr = expr; val->value.expr = expr;
} }
@ -22,22 +25,25 @@ struct Value* make_value(int type, long num, double dec, struct Node* expr) {
} }
struct Value* make_long(long num) { struct Value* make_long(long num) {
return make_value(LONG, num, 0, NULL); return make_value(LONG, num, 0, NULL, NULL);
} }
struct Value* make_double(double dec) { struct Value* make_double(double dec) {
return make_value(DOUBLE, 0, dec, NULL); return make_value(DOUBLE, 0, dec, NULL, NULL);
} }
struct Value* make_true() { struct Value* make_true() {
return make_value(BOOLEAN, 1, 0, NULL); return make_value(BOOLEAN, 1, 0, NULL, NULL);
} }
struct Value* make_false() { struct Value* make_false() {
return make_value(BOOLEAN, 0, 0, NULL); return make_value(BOOLEAN, 0, 0, NULL, NULL);
} }
struct Value* make_boolean(int x) { struct Value* make_boolean(int x) {
return (x)? make_true() : make_false(); return (x)? make_true() : make_false();
} }
struct Value* make_expression(struct Node* expr) { struct Value* make_expression(struct Node* expr) {
return make_value(LAMBDA, 0, 0, expr); return make_value(LAMBDA, 0, 0, expr, NULL);
}
struct Value* make_string(char* str) {
return make_value(STRING, 0, 0, NULL, str);
} }
void delete_value(struct Value* val) { void delete_value(struct Value* val) {
@ -53,6 +59,9 @@ double get_double(struct Value* val) {
struct Node* get_expression(struct Value* val) { struct Node* get_expression(struct Value* val) {
return val->value.expr; return val->value.expr;
} }
char* get_string(struct Value* val) {
return val->value.str;
}
void set_long(struct Value* val, long num) { void set_long(struct Value* val, long num) {
val->type = LONG; val->type = LONG;
@ -66,3 +75,25 @@ void set_expression(struct Value* val, struct Node* expr) {
val->type = LAMBDA; val->type = LAMBDA;
val->value.expr = expr; val->value.expr = expr;
} }
void set_sring(struct Value* val, char* str) {
val->type = STRING;
val->value.str = str;
}
void print_value(struct Value* val) {
if (val->type == BOOLEAN) {
if (get_long(val)) {
printf("true");
} else {
printf("false");
}
} else if (val->type == LONG) {
printf("%li", get_long(val));
} else if (val->type == STRING) {
printf("%s", get_string(val));
} else if (val->type == DOUBLE) {
printf("%lf", get_double(val));
} else { // Assume lambda expression
printf("<LambdaExpression>");
}
}

View file

@ -1,12 +1,13 @@
#ifndef VALUE_H #ifndef VALUE_H
#define VALUE_H #define VALUE_H
enum TypeTag { DOUBLE, LONG, BOOLEAN }; enum TypeTag { DOUBLE, LONG, BOOLEAN, STRING };
typedef union typeval { typedef union typeval {
long num; long num;
double dec; double dec;
struct Node* expr; struct Node* expr;
char* str;
} TypeVal; } TypeVal;
struct Value { struct Value {
@ -15,13 +16,14 @@ struct Value {
}; };
// Constructors // Constructors
struct Value* make_value(int type, long num, double dec, struct Node* expr); struct Value* make_value(int type, long num, double dec, struct Node* expr, char* str);
struct Value* make_long(long num); struct Value* make_long(long num);
struct Value* make_double(double dec); struct Value* make_double(double dec);
struct Value* make_true(); struct Value* make_true();
struct Value* make_false(); struct Value* make_false();
struct Value* make_boolean(int x); struct Value* make_boolean(int x);
struct Value* make_expression(struct Node* expr); struct Value* make_expression(struct Node* expr);
struct Value* make_string(char* str);
// Destructor // Destructor
void delete_value(struct Value* val); void delete_value(struct Value* val);
@ -30,10 +32,14 @@ void delete_value(struct Value* val);
long get_long(struct Value* val); long get_long(struct Value* val);
double get_double(struct Value* val); double get_double(struct Value* val);
struct Node* get_expression(struct Value* val); struct Node* get_expression(struct Value* val);
char* get_string(struct Value* val);
// Setters // Setters
void set_long(struct Value* val, long num); void set_long(struct Value* val, long num);
void set_double(struct Value* val, double dec); void set_double(struct Value* val, double dec);
void set_expression(struct Value* val, struct Node* node); void set_expression(struct Value* val, struct Node* node);
void set_string(struct Value* val, char* str);
void print_value(struct Value* val);
#endif #endif