Skip to content

Commit

Permalink
Adds gets and puts
Browse files Browse the repository at this point in the history
puts only works for literals right now.
gets does not exactly work yet.
  • Loading branch information
lavignes committed Oct 8, 2012
1 parent ab50a46 commit 052b059
Show file tree
Hide file tree
Showing 11 changed files with 209 additions and 7 deletions.
1 change: 1 addition & 0 deletions examples/echo.hkl
@@ -0,0 +1 @@
puts gets
1 change: 1 addition & 0 deletions examples/hello.hkl
@@ -0,0 +1 @@
puts "Hello World!"
14 changes: 14 additions & 0 deletions src/hkl.c
Expand Up @@ -22,10 +22,24 @@ int yyerror(const char* msg)

int main(int argc, const char* argv[])
{
// If there is a filename
if (argv[1])
{
yyin = fopen(argv[1], "r");
if (yyin == NULL)
{
fprintf(stderr, "Can't open: \"%s\"\n", argv[1]);
return 1;
}
}

hklr_init();
yyparse();

hklr_shutdown();

if (yyin != NULL)
fclose(yyin);

return 0;
}
90 changes: 90 additions & 0 deletions src/hkl_expression.c
@@ -1,10 +1,100 @@
#include <stdio.h>
#include <assert.h>

#include "hkl_alloc.h"
#include "hkl_expression.h"

HklExpression* hkl_expression_new(HklExpressionType type, ...)
{
HklExpression* expr = hkl_alloc_object(HklExpression);

expr->type = type;

va_list argp;
va_start(argp, type);

switch (type)
{
case HKL_EXPR_INT:
expr->arg[0].integer = va_arg(argp, int);
break;

case HKL_EXPR_REAL:
expr->arg[0].real = va_arg(argp, double);
break;

case HKL_EXPR_STRING:
expr->arg[0].string = va_arg(argp, HklString*);
break;

default:
break;
}

va_end(argp);

return expr;
}

HklString* hkl_expression_eval_string(HklExpression* expr)
{
assert(expr != NULL);

switch (expr->type)
{
case HKL_EXPR_STRING:
// return a copy of the string
return hkl_string_new_from_string(expr->arg[0].string);
break;

case HKL_EXPR_INT:
return hkl_string_new_from_integer(expr->arg[0].integer);
break;

case HKL_EXPR_REAL:
return hkl_string_new_from_real(expr->arg[0].real);
break;

case HKL_EXPR_GETS:
{
HklString* buffer = hkl_string_new();
uint32_t c;

while (true) {

c = fgetc(stdin);
if (c == (uint32_t) EOF || c == '\n')
break;

hkl_string_cat_character(buffer, c);
}

return buffer;
}
break;

default:
break;
}

assert(false);
return NULL;
}

void hkl_expression_free(HklExpression* expr)
{
assert(expr != NULL);

switch (expr->type)
{
case HKL_EXPR_STRING:
// free the internal string
hkl_string_free(expr->arg[0].string);
break;

default:
break;
}

hkl_free_object(expr);
}
18 changes: 17 additions & 1 deletion src/hkl_expression.h
Expand Up @@ -3,19 +3,35 @@

#include <stdarg.h>

#include "hkl_string.h"

typedef enum HklExpressionType {

HKL_EXPR_INT,
HKL_EXPR_REAL,
HKL_EXPR_STRING
HKL_EXPR_STRING,
HKL_EXPR_GETS

} HklExpressionType;

typedef struct HklExpression
{
HklExpressionType type;

union exprarg {

int integer;
double real;
HklString* string;

} arg[1];

} HklExpression;

HklExpression* hkl_expression_new(HklExpressionType type, ...);

HklString* hkl_expression_eval_string(HklExpression* expr);

void hkl_expression_free(HklExpression* expr);

#endif // HKL_EXPRESSION_H
28 changes: 27 additions & 1 deletion src/hkl_statement.c
@@ -1,4 +1,5 @@
#include <assert.h>
#include <stdio.h>

#include "hkl_alloc.h"
#include "hkl_statement.h"
Expand Down Expand Up @@ -35,10 +36,35 @@ void hkl_statement_exec(HklStatement* stmt)
switch (stmt->type)
{
case HKL_STMT_PUTS:

{
HklString* string = hkl_expression_eval_string(stmt->arg[0].expression);
printf("%s\n", string->utf8_data);
hkl_string_free(string);
}
break;

default:
break;
}
}

void hkl_statement_free(HklStatement* stmt)
{

assert(stmt != NULL);

switch (stmt->type)
{
case HKL_STMT_PUTS:
{
// Free the expression
hkl_expression_free(stmt->arg[0].expression);
}
break;

default:
break;
}

hkl_free_object(stmt);
}
4 changes: 3 additions & 1 deletion src/hkl_statement.h
Expand Up @@ -17,7 +17,7 @@ typedef struct HklStatement
{
HklStatementType type;

union arg {
union stmtarg {

HklExpression* expression;

Expand All @@ -29,4 +29,6 @@ HklStatement* hkl_statement_new(HklStatementType type, ...);

void hkl_statement_exec(HklStatement* stmt);

void hkl_statement_free(HklStatement* stmt);

#endif // HKL_STATEMENT_H
42 changes: 39 additions & 3 deletions src/hkl_string.c
@@ -1,5 +1,6 @@
#include <assert.h>
#include <string.h>
#include <stdio.h>

#include "hkl_string.h"
#include "hkl_alloc.h"
Expand Down Expand Up @@ -73,6 +74,21 @@ HklString* hkl_string_new_from_string(const HklString* string)
return copy;
}

HklString* hkl_string_new_from_integer(int integer)
{
// create a buffer to store the integer
HklString* string = hkl_string_new_from_utf8(" ");
snprintf(string->utf8_data, string->size, "%d", integer);
return string;
}

HklString* hkl_string_new_from_real(double real)
{
HklString* string = hkl_string_new_from_utf8(" ");
snprintf(string->utf8_data, string->size, "%lg", real);
return string;
}

HklString* hkl_string_new_from_utf8(const char* utf8_data)
{
assert(utf8_data != NULL);
Expand All @@ -94,7 +110,7 @@ HklString* hkl_string_new_from_utf8_chunk(const char* utf8_start, const char* ut
HklString* string = hkl_string_new();

string->utf8_data = realloc(string->utf8_data, size + 1);
string->size = size;
string->size = size + 1;

memcpy(string->utf8_data, utf8_start, size);

Expand Down Expand Up @@ -158,22 +174,42 @@ void hkl_string_cat_utf8(HklString* string, const char* utf8_data)
assert(utf8_data[size] == '\0');

// Resize the string to accomidate new data
if (string->size < string->size + size)
if (string->size < string->size + size + 1)
string->utf8_data = realloc(string->utf8_data, string->size + size + 1);

string->length += utf8_length(utf8_data);

memcpy(string->utf8_data + string->size, utf8_data, string->size + size + 1);
memcpy(string->utf8_data + string->size, utf8_data, size + 1);

string->size = string->size + size;

// The string must be NULL terminated by now
// minus 1 because string->size includes null
assert(string->utf8_data[string->size] == '\0');

// The hash is invalid
string->hash = 0;
}

void hkl_string_cat_character(HklString* string, uint32_t character)
{
assert(string != NULL);

// This is a hack

union hack {

char c[5];
uint32_t d;

} str = {.d = character, .c[4] = '\0'};

printf("catting %s\n", str.c);

hkl_string_cat_utf8(string, str.c);
}


void hkl_string_copy(HklString* string, const HklString* src)
{
assert(string != NULL);
Expand Down
6 changes: 6 additions & 0 deletions src/hkl_string.h
Expand Up @@ -39,6 +39,10 @@ Allocate a copy of another HklString.
*/
HklString* hkl_string_new_from_string(const HklString* string);

HklString* hkl_string_new_from_integer(int integer);

HklString* hkl_string_new_from_real(double real);

/**
Allocate a new HklString using utf8 data.
Expand Down Expand Up @@ -85,6 +89,8 @@ Concatinate a HklString with utf8 data.
*/
void hkl_string_cat_utf8(HklString* string, const char* utf8_data);

void hkl_string_cat_character(HklString* string, uint32_t character);

/**
Turns a HklString into an exact copy of another.
Expand Down
2 changes: 1 addition & 1 deletion src/hklr_object.h
Expand Up @@ -56,7 +56,7 @@ typedef struct HklObject {
HklTypes type: 24;
HklFlags flags: 8;

union as {
union asobject {

uint32_t integer;
double real;
Expand Down
10 changes: 10 additions & 0 deletions src/y.tab.y
Expand Up @@ -156,6 +156,9 @@ stmt_list:
if (HKLR.scope_level == 1)
{
hkl_statement_exec($2);

// clean up the statement as we dont need it anymore
hkl_statement_free($2);
}
else
{
Expand Down Expand Up @@ -237,6 +240,10 @@ assign_stmt:
| variable HKL_T_BITWISE_XOR_ASSIGN expr
| variable HKL_T_BITWISE_NOT_ASSIGN expr

// The statemens in a switch should be stored in a normal
// statement list, but use a hklhash to map to the "case nodes"
// in the switch list. This gives us O(logn) jumps and normal waterfall
// execution
switch_stmt:
HKL_T_SWITCH HKL_T_LPAREN expr HKL_T_RPAREN case_list HKL_T_END

Expand Down Expand Up @@ -312,6 +319,9 @@ primary_expr:
$$ = hkl_expression_new(HKL_EXPR_STRING, $1);
}
| HKL_T_GETS
{
$$ = hkl_expression_new(HKL_EXPR_GETS);
}
| HKL_T_TRUE
| HKL_T_FALSE
| HKL_T_NIL
Expand Down

0 comments on commit 052b059

Please sign in to comment.