Skip to content

Commit

Permalink
Merge pull request #1 from Vipul-Cariappa/dev
Browse files Browse the repository at this point in the history
Fixes and Syntax update
  • Loading branch information
Vipul-Cariappa authored Dec 31, 2023
2 parents e650884 + fe69f3a commit 4398ac8
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 61 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,4 @@ _deps
*.yy.c

*tmp*
KariLang
22 changes: 16 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,25 @@ Toy Functional Programming Language
## Example Program

```text
valdef int x = 10
valdef zero: int = 0;
valdef one: int = 1;
valdef two: int = one + one;
funcdef fib n int -> int =
if n < 2 then
funcdef sum(n: int) -> int = _sum(zero, n);
funcdef _sum(c: int, n: int) -> int =
if n == zero then
c
else
_sum(c + n, n + -1);
funcdef fib(n: int) -> int =
if n < two then
n
else
fib(n + -1) + fib(n + -2)
else
fib(n + -1) + fib(n + -two);
funcdef main n int -> int = fib(n)
funcdef main(n: int) -> int = fib(n);
```

To Run
Expand Down
7 changes: 6 additions & 1 deletion src/common.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

#define YYERROR_VERBOSE 1

#include "DS.h"
#include <assert.h>
#include <stdbool.h>
Expand All @@ -8,10 +10,13 @@
extern FILE *yyin;
extern int yylex(void);
extern int yyparse(void);
extern int yywrap(void);
extern void yyerror(char const *s);
extern int yylineno;
extern int column;
extern char *yytext;
extern char *filename;

extern char syntax_error_msg[];

typedef enum {
UNDEFINED,
Expand Down
26 changes: 26 additions & 0 deletions src/interpreter.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,21 @@ bool interpret(int input, int *output) {
while (NULL != (tree = ast_table_iter_next(ast, &key))) {
switch (tree->type) {
case AST_VARIABLE:
if (integer_table_get_ptr(globalIntegers, tree->value.var->name)) {
break;
}
errno = 0;
if (tree->value.var->type == INT) {
assert(integer_table_insert(
globalIntegers, tree->value.var->name,
evaluate_expression(tree->value.var->expression, NULL)
.integer));
break;
}
if (boolean_table_get_ptr(globalBooleans, tree->value.var->name)) {
break;
}
errno = 0;
if (tree->value.var->type == BOOL) {
assert(boolean_table_insert(
globalBooleans, tree->value.var->name,
Expand Down Expand Up @@ -119,11 +128,28 @@ ExpressionResult evaluate_expression(Expression *exp, Context *cxt) {
if (v) {
return (ExpressionResult){.integer = *(int *)v};
}
errno = 0;
v = boolean_table_get_ptr(globalBooleans, exp->value.variable);
if (v) {
return (ExpressionResult){.boolean = *(bool *)v};
}
errno = 0;
AST *tree = ast_table_get_ptr(ast, exp->value.variable);
if (tree) {
ExpressionResult result_exp =
evaluate_expression(tree->value.var->expression, NULL);
if (tree->value.var->type == INT) {
assert(integer_table_insert(
globalIntegers, tree->value.var->name, result_exp.integer));
return result_exp;
}
if (tree->value.var->type == BOOL) {
assert(boolean_table_insert(
globalBooleans, tree->value.var->name, result_exp.boolean));
return result_exp;
}
}

goto error;
}
case PLUS_EXPRESSION:
Expand Down
80 changes: 44 additions & 36 deletions src/lexer.l
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,51 @@
#include "parser.tab.h"
#include <string.h>
#include <ctype.h>

static int next_column = 1;
int column = 1;

#define HANDLE_COLUMN \
column = next_column; \
next_column += strlen(yytext)
%}

%option noyywrap noinput nounput yylineno

%%
"valdef" { return KW_VALDEF; }
"funcdef" { return KW_FUNCDEF; }
"bool" { return KW_BOOL; }
"int" { return KW_INT; }
"true" { return KW_TRUE; }
"false" { return KW_FALSE; }
"if" { return KW_IF; }
"then" { return KW_THEN; }
"else" { return KW_ELSE; }
"," { return COMMA; }
"+" { return PLUS; }
"-" { return MINUS; }
"*" { return MULTIPLY; }
"/" { return DIVIDE; }
"%" { return MODULO; }
"&&" { return AND; }
"||" { return OR; }
"!" { return NOT; }
"==" { return EQUALS; }
"!=" { return NOT_EQUALS; }
">" { return GREATER; }
"<" { return LESSER; }
">=" { return GREATER_EQUALS; }
"<=" { return LESSER_EQUALS; }
"->" { return RETURN; }
"(" { return OPEN_BRACKETS; }
")" { return CLOSE_BRACKETS; }
"=" { return ASSIGN; }
[0-9]* { yylval.integer = atoi(yytext); return INTEGER; }
[a-zA-Z_][0-9a-zA-Z_]* { yylval.identifier = strdup(yytext); return IDENTIFIER; }
[ \n\t] { ; }
. { fprintf(stderr, "Unexpected Token\n"); return YYUNDEF; }
"valdef" { HANDLE_COLUMN; return KW_VALDEF; }
"funcdef" { HANDLE_COLUMN; return KW_FUNCDEF; }
"bool" { HANDLE_COLUMN; return KW_BOOL; }
"int" { HANDLE_COLUMN; return KW_INT; }
"true" { HANDLE_COLUMN; return KW_TRUE; }
"false" { HANDLE_COLUMN; return KW_FALSE; }
"if" { HANDLE_COLUMN; return KW_IF; }
"then" { HANDLE_COLUMN; return KW_THEN; }
"else" { HANDLE_COLUMN; return KW_ELSE; }
";" { HANDLE_COLUMN; return STATEMENT_END; }
":" { HANDLE_COLUMN; return TYPE_OF; }
"," { HANDLE_COLUMN; return COMMA; }
"+" { HANDLE_COLUMN; return PLUS; }
"-" { HANDLE_COLUMN; return MINUS; }
"*" { HANDLE_COLUMN; return MULTIPLY; }
"/" { HANDLE_COLUMN; return DIVIDE; }
"%" { HANDLE_COLUMN; return MODULO; }
"&&" { HANDLE_COLUMN; return AND; }
"||" { HANDLE_COLUMN; return OR; }
"!" { HANDLE_COLUMN; return NOT; }
"==" { HANDLE_COLUMN; return EQUALS; }
"!=" { HANDLE_COLUMN; return NOT_EQUALS; }
">" { HANDLE_COLUMN; return GREATER; }
"<" { HANDLE_COLUMN; return LESSER; }
">=" { HANDLE_COLUMN; return GREATER_EQUALS; }
"<=" { HANDLE_COLUMN; return LESSER_EQUALS; }
"->" { HANDLE_COLUMN; return RETURN; }
"(" { HANDLE_COLUMN; return OPEN_BRACKETS; }
")" { HANDLE_COLUMN; return CLOSE_BRACKETS; }
"=" { HANDLE_COLUMN; return ASSIGN; }
[0-9]* { HANDLE_COLUMN; yylval.integer = atoi(yytext); return INTEGER; }
[a-zA-Z_][0-9a-zA-Z_]* { HANDLE_COLUMN; yylval.identifier = strdup(yytext); return IDENTIFIER; }
[ \t]+ { HANDLE_COLUMN; }
[\n] { HANDLE_COLUMN; next_column = 1; }
. { HANDLE_COLUMN; return YYUNDEF; }
%%

int yywrap(void) {
return 1;
}
9 changes: 7 additions & 2 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ IMPLEMENT_HASH_FUNCTION;
DS_TABLE_DEF(ast, AST, NULL);

ast_table_t *ast;
char *filename;

int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "File and input required to execute the program\n");
return 1;
}

char *filename = argv[1];
filename = argv[1];

FILE *file = fopen(filename, "r");
if (file == NULL) {
Expand All @@ -31,7 +32,11 @@ int main(int argc, char *argv[]) {

ast = ast_table_new(100);

yyparse();
if (yyparse()) {
fclose(file);
fprintf(stderr, "%s", syntax_error_msg);
return 1;
}
/* END */

fclose(file);
Expand Down
34 changes: 18 additions & 16 deletions src/parser.y
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
%{
#include "common.h"

#define ERROR_MSG_LEN 500
char syntax_error_msg[ERROR_MSG_LEN];
%}

%union {
Expand All @@ -20,6 +23,8 @@
%token KW_THEN
%token KW_ELSE
%token COMMA
%token STATEMENT_END
%token TYPE_OF
%token ASSIGN
%token PLUS
%token MINUS
Expand Down Expand Up @@ -58,23 +63,19 @@

%%
input: %empty
| input value_definition { assert(ast_table_insert(ast, ($2)->name, (AST){.type = AST_VARIABLE, .value.var = $2})); }
| input function_definition { assert(ast_table_insert(ast, ($2)->funcname, (AST){.type = AST_FUNCTION, .value.func = $2})); };
| input value_definition { (ast_table_insert(ast, ($2)->name, (AST){.type = AST_VARIABLE, .value.var = $2})); }
| input function_definition { (ast_table_insert(ast, ($2)->funcname, (AST){.type = AST_FUNCTION, .value.func = $2})); };

function_definition: KW_FUNCDEF IDENTIFIER function_definition_arguments RETURN KW_BOOL ASSIGN expression { $$ = set_function_return_value(set_function_name($3, $2), BOOL, $7); }
| KW_FUNCDEF IDENTIFIER function_definition_arguments RETURN KW_INT ASSIGN expression { $$ = set_function_return_value(set_function_name($3, $2), INT, $7);};
function_definition: KW_FUNCDEF IDENTIFIER OPEN_BRACKETS function_definition_arguments CLOSE_BRACKETS RETURN KW_BOOL ASSIGN expression STATEMENT_END { $$ = set_function_return_value(set_function_name($4, $2), BOOL, $9); }
| KW_FUNCDEF IDENTIFIER OPEN_BRACKETS function_definition_arguments CLOSE_BRACKETS RETURN KW_INT ASSIGN expression STATEMENT_END { $$ = set_function_return_value(set_function_name($4, $2), INT, $9);};

function_definition_arguments: IDENTIFIER KW_BOOL { $$ = add_function_argument(make_function(), $1, BOOL); }
| OPEN_BRACKETS IDENTIFIER KW_BOOL CLOSE_BRACKETS { $$ = add_function_argument(make_function(), $2, BOOL); }
| IDENTIFIER KW_INT { $$ = add_function_argument(make_function(), $1, INT); }
| OPEN_BRACKETS IDENTIFIER KW_INT CLOSE_BRACKETS { $$ = add_function_argument(make_function(), $2, INT); }
| IDENTIFIER KW_BOOL function_definition_arguments { $$ = add_function_argument($3, $1, BOOL); }
| OPEN_BRACKETS IDENTIFIER KW_BOOL CLOSE_BRACKETS function_definition_arguments { $$ = add_function_argument($5, $2, BOOL); }
| IDENTIFIER KW_INT function_definition_arguments { $$ = add_function_argument($3, $1, INT); }
| OPEN_BRACKETS IDENTIFIER KW_INT CLOSE_BRACKETS function_definition_arguments { $$ = add_function_argument($5, $2, INT); };
function_definition_arguments: IDENTIFIER TYPE_OF KW_BOOL { $$ = add_function_argument(make_function(), $1, BOOL); }
| IDENTIFIER TYPE_OF KW_INT { $$ = add_function_argument(make_function(), $1, INT); }
| IDENTIFIER TYPE_OF KW_BOOL COMMA function_definition_arguments { $$ = add_function_argument($5, $1, BOOL); }
| IDENTIFIER TYPE_OF KW_INT COMMA function_definition_arguments { $$ = add_function_argument($5, $1, INT); }

value_definition: KW_VALDEF KW_BOOL IDENTIFIER ASSIGN expression { $$ = make_variable($3, BOOL, $5); }
| KW_VALDEF KW_INT IDENTIFIER ASSIGN expression { $$ = make_variable($3, INT, $5); };
value_definition: KW_VALDEF IDENTIFIER TYPE_OF KW_BOOL ASSIGN expression STATEMENT_END { $$ = make_variable($2, BOOL, $6); }
| KW_VALDEF IDENTIFIER TYPE_OF KW_INT ASSIGN expression STATEMENT_END { $$ = make_variable($2, INT, $6); };

expression: IDENTIFIER { $$ = make_variable_expression($1); }
| INTEGER { $$ = make_integer_expression($1); }
Expand Down Expand Up @@ -102,6 +103,7 @@ function_call_arguments: expression { $$ = add_function_call_argument_expression
| expression COMMA function_call_arguments { $$ = add_function_call_argument_expression($3, $1); };
%%

void yyerror(char const *s) {
fprintf(stderr, "PARSER ERROR: %s\n", s);
void yyerror(char const *str) {
snprintf(syntax_error_msg, ERROR_MSG_LEN,
"ERROR: %s in %s:%d:%d\n", str, filename, yylineno, column);
}

0 comments on commit 4398ac8

Please sign in to comment.