Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Refactored Statements and Expressions

This should hopefully make these beasts more managable.
  • Loading branch information...
commit 6f07517c083f8190469a3efcbb9d607cfed6ce49 1 parent 79a80c9
@pyrated pyrated authored
View
2  examples/assign.hkl
@@ -1,4 +1,4 @@
a = "Hello World\n"
puts a
b = a
-puts b
+puts b
View
7 src/Makefile.am
@@ -7,7 +7,10 @@ bin_PROGRAMS = hkl testbed
hkl_SOURCES = y.tab.y lex.yy.l hkl_string.c hkl_hash.c hkl_tree.c hkl.c \
hkl_deque.c hklr.c hklr_object.c hklr_expression.c hklr_statement.c \
-hkl_value.c hkl_list.c
+hkl_value.c hkl_list.c \
+expression/hklr_op_plus.c \
+statement/hklr_statement_puts.c \
+statement/hklr_statement_assign.c
testbed_SOURCES = hkl_tree.c hkl_string.c hkl_test.c hklr.c hklr_object.c \
-hkl_deque.c hkl_hash.c hkl_list.c test/hash.c test/traversal.c
+hkl_deque.c hkl_hash.c hkl_list.c hkl_value.c test/hash.c test/traversal.c
View
126 src/expression/hklr_op_plus.c
@@ -0,0 +1,126 @@
+#include <assert.h>
+
+#include "hkl_value.h"
+
+HklValue* hklr_op_plus(HklValue* left_value, HklValue* right_value)
+{
+ HklValue* result = NULL;
+ bool left_updated = false, right_updated = false;
+
+ // Dereference left and right sides
+ if (left_value->type == HKL_TYPE_REF)
+ {
+ left_updated = true;
+ left_value = hklr_object_dereference(left_value->as.object);
+ }
+
+ if (right_value->type == HKL_TYPE_REF)
+ {
+ right_updated = true;
+ right_value = hklr_object_dereference(right_value->as.object);
+ }
+
+ switch (left_value->type)
+ {
+ case HKL_TYPE_INT:
+ switch(right_value->type)
+ {
+ case HKL_TYPE_INT:
+ result = hkl_value_new(HKL_TYPE_INT,
+ left_value->as.integer + right_value->as.integer);
+ break;
+
+ case HKL_TYPE_REAL:
+ result = hkl_value_new(HKL_TYPE_REAL,
+ left_value->as.integer + right_value->as.real);
+ break;
+
+ case HKL_TYPE_STRING:
+ assert(false);
+ break;
+
+ default:
+ assert(false);
+ break;
+ }
+ break; // HKL_TYPE_INT
+
+ case HKL_TYPE_REAL:
+ switch(right_value->type)
+ {
+ case HKL_TYPE_INT:
+ result = hkl_value_new(HKL_TYPE_REAL,
+ left_value->as.real + right_value->as.integer);
+ break;
+
+ case HKL_TYPE_REAL:
+ result = hkl_value_new(HKL_TYPE_REAL,
+ left_value->as.real + right_value->as.real);
+ break;
+
+ case HKL_TYPE_STRING:
+ assert(false);
+ break;
+
+ default:
+ assert(false);
+ break;
+ }
+ break; // HKL_TYPE_REAL
+
+ case HKL_TYPE_STRING:
+ switch(right_value->type)
+ {
+
+ case HKL_TYPE_INT:
+ {
+ result = hkl_value_new(HKL_TYPE_STRING,
+ hkl_string_new_from_string(left_value->as.string));
+ HklString* right_string =
+ hkl_string_new_from_integer(right_value->as.integer);
+ hkl_string_cat(result->as.string, right_string);
+ hkl_string_free(right_string);
+ }
+ break;
+
+ case HKL_TYPE_REAL:
+ {
+ result = hkl_value_new(HKL_TYPE_STRING,
+ hkl_string_new_from_string(left_value->as.string));
+ HklString* right_string =
+ hkl_string_new_from_real(right_value->as.real);
+ hkl_string_cat(result->as.string, right_string);
+ hkl_string_free(right_string);
+ }
+ break;
+
+ case HKL_TYPE_STRING:
+ result = hkl_value_new(HKL_TYPE_STRING,
+ hkl_string_new_from_string(left_value->as.string));
+
+ hkl_string_cat(result->as.string, right_value->as.string);
+ break;
+
+ default:
+ assert(false);
+ break;
+ }
+ break; // HKL_TYPE_STRING
+
+ default:
+ assert(false);
+ break;
+ }
+
+ if (left_updated)
+ {
+ hkl_value_free(left_value);
+ }
+
+ if (right_updated)
+ {
+ hkl_value_free(right_value);
+ }
+
+ return result;
+}
View
99 src/hklr_expression.c
@@ -5,6 +5,8 @@
#include "hkl_alloc.h"
#include "hklr_expression.h"
+extern HklValue* hklr_op_plus(HklValue* left_value, HklValue* right_value);
+
HklrExpression* hklr_expression_new(HklExpressionType type, ...)
{
assert(type != HKL_EXPR_NONE);
@@ -60,6 +62,9 @@ HklValue* hklr_expression_eval(HklrExpression* expr)
switch (expr->type)
{
+ case HKL_EXPR_NIL:
+ return hkl_value_new(HKL_TYPE_NIL);
+ break;
case HKL_EXPR_INT:
return hkl_value_new(HKL_TYPE_INT, expr->arg[0].integer);
@@ -149,98 +154,8 @@ HklValue* hklr_expression_eval(HklrExpression* expr)
switch (expr->arg[1].op)
{
case HKL_OP_PLUS:
- switch (left_value->type)
- {
- case HKL_TYPE_INT:
- switch(right_value->type)
- {
- case HKL_TYPE_INT:
- result = hkl_value_new(HKL_TYPE_INT,
- left_value->as.integer + right_value->as.integer);
- break;
-
- case HKL_TYPE_REAL:
- result = hkl_value_new(HKL_TYPE_INT,
- left_value->as.integer + right_value->as.real);
- break;
-
- case HKL_TYPE_STRING:
- assert(false);
- break;
-
- default:
- assert(false);
- break;
- }
- break; // HKL_TYPE_INT
-
- case HKL_TYPE_REAL:
- switch(right_value->type)
- {
- case HKL_TYPE_INT:
- result = hkl_value_new(HKL_TYPE_REAL,
- left_value->as.real + right_value->as.integer);
- break;
-
- case HKL_TYPE_REAL:
- result = hkl_value_new(HKL_TYPE_REAL,
- left_value->as.real + right_value->as.real);
- break;
-
- case HKL_TYPE_STRING:
- assert(false);
- break;
-
- default:
- assert(false);
- break;
- }
- break; // HKL_TYPE_REAL
-
- case HKL_TYPE_STRING:
- switch(right_value->type)
- {
-
- case HKL_TYPE_INT:
- {
- result = hkl_value_new(HKL_TYPE_STRING,
- hkl_string_new_from_string(left_value->as.string));
- HklString* right_string =
- hkl_string_new_from_integer(right_value->as.integer);
- hkl_string_cat(result->as.string, right_string);
- hkl_string_free(right_string);
- }
- break;
-
- case HKL_TYPE_REAL:
- {
- result = hkl_value_new(HKL_TYPE_STRING,
- hkl_string_new_from_string(left_value->as.string));
- HklString* right_string =
- hkl_string_new_from_real(right_value->as.real);
- hkl_string_cat(result->as.string, right_string);
- hkl_string_free(right_string);
- }
- break;
-
- case HKL_TYPE_STRING:
- result = hkl_value_new(HKL_TYPE_STRING,
- hkl_string_new_from_string(left_value->as.string));
-
- hkl_string_cat(result->as.string, right_value->as.string);
- break;
-
- default:
- assert(false);
- break;
- }
- break; // HKL_TYPE_STRING
-
- default:
- assert(false);
- break;
- }
- break; // HKL_OP_PLUS
+ result = hklr_op_plus(left_value, right_value);
+ break;
default:
assert(false);
View
1  src/hklr_expression.h
@@ -9,6 +9,7 @@
typedef enum HklExpressionType
{
HKL_EXPR_NONE,
+ HKL_EXPR_NIL,
HKL_EXPR_INT,
HKL_EXPR_REAL,
HKL_EXPR_STRING,
View
30 src/hklr_object.c
@@ -4,6 +4,7 @@
#include "hklr_object.h"
#include "hkl_alloc.h"
#include "hklr.h"
+#include "hkl_value.h"
HklrObject* hklr_object_new(HklType type, HklFlag flags, ...)
{
@@ -56,6 +57,35 @@ HklrObject* hklr_object_new(HklType type, HklFlag flags, ...)
return object;
}
+HklValue* hklr_object_dereference(HklrObject* object)
+{
+ assert(object != NULL);
+
+ switch (object->type)
+ {
+ case HKL_TYPE_NIL:
+ return hkl_value_new(HKL_TYPE_NIL);
+ break;
+
+ case HKL_TYPE_INT:
+ return hkl_value_new(HKL_TYPE_INT, object->as.integer);
+ break;
+
+ case HKL_TYPE_REAL:
+ return hkl_value_new(HKL_TYPE_REAL, object->as.real);
+ break;
+
+ case HKL_TYPE_STRING:
+ return hkl_value_new(HKL_TYPE_STRING, hkl_string_new_from_string(object->as.string));
+ break;
+
+ default:
+ assert(false);
+ return NULL;
+ break;
+ }
+}
+
void hklr_object_free(HklrObject* object)
{
assert(object != NULL);
View
2  src/hklr_object.h
@@ -89,6 +89,8 @@ garbage collected by the HKLR.
*/
HklrObject* hklr_object_new(HklType type, HklFlag flags, ...);
+struct HklValue* hklr_object_dereference(HklrObject* object);
+
/**
Free resources used by a HklObject
View
126 src/hklr_statement.c
@@ -5,6 +5,9 @@
#include "hklr_statement.h"
#include "hklr.h"
+extern void hklr_statement_puts(HklrExpression* expr);
+void hklr_statement_assign(HklrExpression* lhs, HklrExpression* rhs);
+
HklrStatement* hklr_statement_new(HklStatementType type, ...)
{
assert(type != HKL_STMT_NONE);
@@ -45,55 +48,7 @@ void hklr_statement_exec(HklrStatement* stmt)
{
case HKL_STMT_PUTS:
- {
- HklValue* value = hklr_expression_eval(stmt->arg[0].expression);
-
- assert(value != NULL);
-
- switch (value->type)
- {
- case HKL_TYPE_INT:
- fprintf(stdout, "%i", value->as.integer);
- break;
-
- case HKL_TYPE_REAL:
- fprintf(stdout, "%lg", value->as.real);
- break;
-
- case HKL_TYPE_STRING:
- fprintf(stdout, "%s", value->as.string->utf8_data);
- break;
-
- case HKL_TYPE_REF:
- {
- HklrObject* object = value->as.object;
- assert(object != NULL);
-
- switch(object->type)
- {
- case HKL_TYPE_INT:
- fprintf(stdout, "%i", object->as.integer);
- break;
- case HKL_TYPE_REAL:
- fprintf(stdout, "%lg", object->as.real);
- break;
- case HKL_TYPE_STRING:
- fprintf(stdout, "%s", object->as.string->utf8_data);
- break;
- }
- }
- break; // HKL_TYPE_REF
-
- default:
- assert(false);
- break;
- }
-
- // flush the output
- fflush(stdout);
-
- hkl_value_free(value);
- }
+ hklr_statement_puts(stmt->arg[0].expression);
break;
case HKL_STMT_HKLR:
@@ -112,78 +67,7 @@ void hklr_statement_exec(HklrStatement* stmt)
break;
case HKL_STMT_ASSIGN:
- {
-
- // Evaluate the left hand side and then discard the value object
- HklValue* vobj = hklr_expression_eval(stmt->arg[0].expression);
- HklrObject* object = vobj->as.object;
- hkl_value_free(vobj);
-
- HklValue* value = hklr_expression_eval(stmt->arg[1].expression);
-
- assert(object != NULL);
- assert(value != NULL);
-
- // wipe out the original value
- // if need be
- switch (object->type)
- {
- case HKL_TYPE_STRING:
- hkl_string_free(object->as.string);
- break;
-
- default:
- break;
- }
-
- switch (value->type)
- {
- case HKL_TYPE_INT:
- object->type = HKL_TYPE_INT;
- object->as.integer = value->as.integer;
- break;
-
- case HKL_TYPE_REAL:
- object->type = HKL_TYPE_REAL;
- object->as.real = value->as.real;
- break;
-
- case HKL_TYPE_STRING:
- object->type = HKL_TYPE_STRING;
- object->as.string = hkl_string_new_from_string(value->as.string);
- break;
-
- case HKL_TYPE_REF:
- {
- HklrObject* ref = value->as.object;
- assert(ref != NULL);
-
- switch(ref->type)
- {
- case HKL_TYPE_INT:
- object->type = HKL_TYPE_INT;
- object->as.integer = ref->as.integer;
- break;
-
- case HKL_TYPE_REAL:
- object->type = HKL_TYPE_REAL;
- object->as.real = ref->as.real;
- break;
-
- case HKL_TYPE_STRING:
- object->type = HKL_TYPE_STRING;
- object->as.string = hkl_string_new_from_string(ref->as.string);
- break;
-
- default:
- break;
- }
- }
- break; // HKL_TYPE_REF
- }
-
- hkl_value_free(value);
- }
+ hklr_statement_assign(stmt->arg[0].expression, stmt->arg[1].expression);
break; // HKL_STMT_ASSIGN
default:
View
66 src/statement/hklr_statement_assign.c
@@ -0,0 +1,66 @@
+#include <assert.h>
+
+#include "hklr_expression.h"
+
+void hklr_statement_assign(HklrExpression* lhs, HklrExpression* rhs)
+{
+ // Evaluate the left hand side and then discard the value object
+ HklValue* vobj = hklr_expression_eval(lhs);
+ HklrObject* object = vobj->as.object;
+ hkl_value_free(vobj);
+
+ HklValue* value = hklr_expression_eval(rhs);
+
+ assert(object != NULL);
+ assert(value != NULL);
+
+ // dereference the objcet
+ if (value->type == HKL_TYPE_REF)
+ {
+ HklValue* temp = value;
+ value = hklr_object_dereference(value->as.object);
+ hkl_value_free(temp);
+ }
+
+ // wipe out the original value
+
+ // Composite objects will
+ // create new objects to replace the variable
+ // and decrease the ref count of the original
+ switch (object->type)
+ {
+ case HKL_TYPE_STRING:
+ hkl_string_free(object->as.string);
+ break;
+
+ default:
+ break;
+ }
+
+ switch (value->type)
+ {
+ case HKL_TYPE_NIL:
+ object->type = HKL_TYPE_NIL;
+ break;
+
+ case HKL_TYPE_INT:
+ object->type = HKL_TYPE_INT;
+ object->as.integer = value->as.integer;
+ break;
+
+ case HKL_TYPE_REAL:
+ object->type = HKL_TYPE_REAL;
+ object->as.real = value->as.real;
+ break;
+
+ case HKL_TYPE_STRING:
+ object->type = HKL_TYPE_STRING;
+ object->as.string = hkl_string_new_from_string(value->as.string);
+ break;
+
+ default:
+ break;
+ }
+
+ hkl_value_free(value);
+}
View
46 src/statement/hklr_statement_puts.c
@@ -0,0 +1,46 @@
+#include <assert.h>
+
+#include "hklr_expression.h"
+
+void hklr_statement_puts(HklrExpression* expr)
+{
+ assert(expr != NULL);
+
+ HklValue* value = hklr_expression_eval(expr);
+
+ // derefence the object
+ if (value->type == HKL_TYPE_REF)
+ {
+ HklValue* temp = value;
+ value = hklr_object_dereference(value->as.object);
+ hkl_value_free(temp);
+ }
+
+ switch (value->type)
+ {
+ case HKL_TYPE_NIL:
+ fprintf(stdout, "nil");
+ break;
+
+ case HKL_TYPE_INT:
+ fprintf(stdout, "%i", value->as.integer);
+ break;
+
+ case HKL_TYPE_REAL:
+ fprintf(stdout, "%lg", value->as.real);
+ break;
+
+ case HKL_TYPE_STRING:
+ fprintf(stdout, "%s", value->as.string->utf8_data);
+ break;
+
+ default:
+ assert(false);
+ break;
+ }
+
+ // flush the output
+ fflush(stdout);
+
+ hkl_value_free(value);
+}
View
3  src/y.tab.y
@@ -363,6 +363,9 @@ primary_expr:
| HKL_T_TRUE
| HKL_T_FALSE
| HKL_T_NIL
+ {
+ $$ = hklr_expression_new(HKL_EXPR_NIL);
+ }
| HKL_T_NULL
| HKL_T_SELF
| variable
Please sign in to comment.
Something went wrong with that request. Please try again.