v0.9.5 release!

master
xerox 5 years ago
parent 6000d5d8b5
commit 527a4143b6

@ -1,49 +1,141 @@
# Deon programming language V0.9.2.1 # Deon programming language V0.9.5
My computer programming language made with LEX/YACC written in C. (interpreted) My computer programming language made with LEX/YACC written in C. (interpreted)
# Downloads
<hr/>
Win-32: <a href=""/>download</a>
Win-64: <a href=""/>download</a>
Linux-32: <a href=""/>download</a>
Linux-64: <a href=""/>download</a>
# Hello World. # Hello World.
<hr/>
Hello world in Deon.
``` ```
def Main : { def main:
printf[ "hello world" ]; {
print["hello world"];
}; };
call Main; call main;
``` ```
Requirements to making a program:
1.) a struct/function.
2.) a call statement.
# Variables # Variables
Variables are stored in a hashmap for quick and easy access. Variables also support type juggling. When you define a variable its type will be assumed when parsed. <hr/>
- Variables support "type juggling" where types are assumed at runtime.
- Variables can be assigned to each other even if they are different types.
```
/* main function */
def main:
{
my_var = 121231; /* int */
print[my_var];
my_var = -123.122; /* double */
print[my_var];
my_var = "cool string"; /* null terminating string */
print[my_var];
my_var = 'c'; /* char */
print[my_var];
my_var = { print[ "hello world" ]; }; /* lambda function */
call my_var;
};
call main;
```
# Expressions
- As ov v0.9.5 expressions are only supported for int types, I need to recode the entire expression parsing system
to support up to doubles.
```
def main:
{
var = 10 + (5 * 2 / (11 % 2));
/* should print 20 */
print[var];
};
call main;
```
# Scope
- As of v0.9.5 there is not scope inside of this programming language.
``` ```
myint = 121231; /* changes var from 10 to 100 */
mydouble = -123.122; def another_function:
mystring = "cool string"; {
mychar = 'c'; // char var = 100;
myfunction = { printf[ "hello world" ]; }; (statement list) };
def main:
{
var = 10;
/* should print 10 */
print[var];
call another_function;
/* should print 100 */
print[var];
};
call main;
``` ```
# Logic # Logic
Logic is first evaluated and if deemed valid then a list of statements will be executed. <hr/>
- while loops are if statements
- As of version 0.9.5, logic conditions must only be variables.
### If statements
As stated above, if statement conditions must be a variable.
``` ```
if [ 10 > 9 ]: { def main:
printf [ "10 is bigger than 9!" ]; {
newInt = 100; var = 1;
if[var]: /* condition must be a variable */
{
print["var was 1"];
var = 0;
};
if[var]:
{
print["this wont print! (or shouldnt)"];
};
}; };
call main;
if [ {int} newInt > 99 ]: { ```
printf [ "newInt is bigger than 99" ]; ### While loop
```
def main:
{
var = 1;
/* loop that runs forever */
while[var]:
{
print["this will run forever"];
print["it also wont stack overflow, so dont worry"];
};
}; };
call main;
``` ```
# Functions # Functions
Functions can be declared inside of a struct and accessed by anyone who uses the scope resolution operator. Do not mistake structs as functions just because you can interact with them in the same way. Functions do not have "scope" like structs do. Functions can interact with all elements in the parenting struct including other functions, and those functions local variables. - Functions can be defined as variables (lambda) or defined normally.
``` ```
def NewStruct : { def my_function:
someFunction = { {
printf[ "hello world" ]; some_function = {
print["hello world"];
}; };
call some_function;
}; };
call NewStruct; call my_function;
``` ```
# Coming soon # Redefinitions
TCP networking, file handling, and finally loops! - As of v0.9.5 everything in this programming language can be redefined. That means everything, including the function that
is currently being executed.
```
def main:
{
main = {
print["i just redefined main"];
};
};
call main;
call main;
```

@ -0,0 +1,84 @@
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "types.h"
#include "y.tab.h"
void yyerror(char *);
extern YYSTYPE yylval;
extern FILE *yyin;
int yylineno;
%}
%%
\/\*.*?\*\/ { ; // comment }
-?[0-9]+ { yylval.int_num = atoi(yytext); return INTEGER; }
\'[ -~]\' { yylval.byte_num = yytext[1]; return CHAR; }
[-()<>=+*/:;,%{}\[\]] { return *yytext; }
"if" { return IF; }
"else" { return ELSE; }
"print" { return PRINT_TOKEN; }
"string" { return KEYWORD_S; }
"while" { return WHILE; }
"int" { return KEYWORD_I; }
"def" { return DEF;}
"call" { return CALL; }
"char" { return KEYWORD_C; }
"++" { return INCREASE; }
"--" { return DECREASE; }
\"(\\.|[^"\\])*\" { yytext++; yytext[strlen(yytext)-1] = 0; yylval.str_ptr = strdup(yytext); return STRING; }
[a-zA-Z0-9_]+ { yylval.str_ptr = strdup(yytext); return VARNAME; }
-?[0-9]*\.[0-9]+ { yylval.double_num = atof(yytext); return DOUBLEVAR; }
"\n" { yylineno++; }
[ ?\t\n\r]
. printf("invalid character on line %d, '%s'\n", yylineno, yytext);
<<EOF>> { exit(0); }
%%
int yywrap(void) {
return 1;
}
int main(int argc, char* argv[])
{
_var_map = malloc(sizeof(map_void_t));
map_init(_var_map);
_temp_statement_head = NULL;
_function_list = NULL;
FILE *fh;
if (argc > 1)
{
if (strcmp(argv[1],"help") == 0 || strcmp(argv[1],"-help") == 0
|| strcmp(argv[1],"--help") == 0 || strcmp(argv[1],"h") == 0
|| strcmp(argv[1],"-h") == 0)
{
printf("[ HELP ] put a file/path as the first flag.\n");
printf("[ HELP ] -h, -help, --help, help, h: Prints this.\n");
printf("[ HELP ] -d, d, -debug, debug: Enter REPL mode.\n");
}
else if (strcmp(argv[1],"-debug") == 0 || strcmp(argv[1],"-d") == 0
|| strcmp(argv[1],"d") == 0 || strcmp(argv[1],"debug") == 0)
{
_DEON_DEBUG = 1;
printf(">>> ");
yyparse();
}
else if (fh = fopen(argv[1], "r"))
{
yyin = fh;
yyparse();
fclose(fh);
}
else
{
printf("[ ERROR ] please enter a correct command. try --help\n");
fclose(fh);
}
} else
printf("[ ERROR ] missing input file. Try --help?\n");
return 0;
}

@ -0,0 +1,119 @@
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "types.h"
#include "parser/parser.c"
#include "functions/functions.c"
#include "logic/logic.c"
#include "print/print.c"
#include "vars/vars.c"
int yylex(void);
void yyerror(char *);
extern int yylineno;
%}
/* doing these before multiplication and division because they have a lower presidence */
%left '<' '>'
%left '+' '-'
/* doing this last so they have a higher presidence */
%left '*' '/' '%'
%union {
char* str_ptr;
int int_num;
unsigned uint_num;
char byte_num;
double double_num;
float float_num;
struct node_info *node_ptr;
}
%token INCREASE DECREASE PRINT_TOKEN IF END KEYWORD_S KEYWORD_I KEYWORD_C QUOTE ELSE WHILE DEF CALL
%token <int_num> INTEGER
%token <str_ptr> STRING VARNAME
%token <byte_num> CHAR
%token <double_num> DOUBLEVAR
%token <float_num> FLOAT_NUM
%type <int_num> EXPR
%type <node_ptr> STMT PRINT VARIABLE FUNC STMT_LIST LOGIC
%%
PROGRAM:
MAIN '\n'
|
;
MAIN:
MAIN FUNC ';' { if (_DEON_DEBUG == true ) { printf(">>> "); exec_stmt($2); } else { exec_stmt($2); } }
|
;
FUNC:
DEF VARNAME ':' '{' STMT_LIST '}' { $$ = create_function($2, $5); }
| CALL VARNAME { $$ = create_function_call($2); }
;
STMT_LIST:
STMT ';' { $$ = create_compound_statement($1, _temp_statement_head); }
| STMT_LIST STMT ';' { $$ = add_to_compound_statement($2, $1); }
;
STMT:
VARIABLE { $$ = $1; }
| LOGIC { $$ = $1; }
| FUNC { $$ = $1; }
| PRINT_TOKEN '[' PRINT ']' { $$ = $3; }
| '{' STMT_LIST '}' { $$ = $2; }
;
LOGIC:
IF '[' VARNAME ']' ':' '{' STMT_LIST '}' { $$ = create_logic_node(create_logic(IF_LOGIC, $7, $3)); }
| WHILE '[' VARNAME ']' ':' '{' STMT_LIST '}' { $$ = create_logic_node(create_logic(WHILE_LOGIC, $7, $3)); }
;
VARIABLE:
VARNAME '=' STRING { $$ = create_variable_const($1, (void *) $3, VAR_STRING);}
| VARNAME '=' EXPR { $$ = create_variable_const($1, alloc_value(&$3, VAR_INT), VAR_INT);}
| VARNAME '=' CHAR { $$ = create_variable_const($1, alloc_value(&$3, VAR_BYTE), VAR_BYTE);}
| VARNAME '=' DOUBLEVAR { $$ = create_variable_const($1, alloc_value(&$3, VAR_DOUBLE), VAR_DOUBLE);}
| VARNAME '=' '{' STMT_LIST '}' { $$ = create_function($1, $4); }
| VARNAME '=' VARNAME { $$ = move_value($1, $3); }
;
EXPR:
INTEGER { $$ = $1; }
| EXPR '+' EXPR { $$ = $1 + $3; }
| EXPR '-' EXPR { $$ = $1 - $3; }
| EXPR '*' EXPR { $$ = $1 * $3; }
| EXPR '/' EXPR { $$ = $1 / $3; }
| EXPR '%' EXPR { $$ = $1 % $3; }
| EXPR '>' EXPR { if ($1 > $3) { $$ = 1; } else { $$ = 0;}}
| EXPR '<' EXPR { if ($1 < $3) { $$ = 1; } else { $$ = 0;}}
| INCREASE EXPR { $$ = $2 + 1; }
| EXPR INCREASE { $$ = $1 + 1; }
| DECREASE EXPR { $$ = $2 - 1; }
| EXPR DECREASE { $$ = $1 - 1; }
| '(' EXPR ')' { $$ = $2; }
;
PRINT:
VARNAME { $$ = create_print_variable($1); }
| EXPR { $$ = create_print_statement(VAR_INT, alloc_value(&$1, VAR_INT)); }
| STRING { $$ = create_print_statement(VAR_STRING, $1); }
;
%%
void yyerror(char *s)
{
fprintf(stderr, "Error on line %d, %s\n", yylineno, s);
}

@ -0,0 +1,125 @@
#ifndef FUNCTIONS_C
#define FUNCTIONC_C
#include "functions.h"
/*
Author: xerox
Update: 1/20/2020
create a function given the name of the function and the statements
*/
static node_info *create_function(char *p_name, node_info *p_stmts)
{
node_info *new_node = malloc(sizeof(node_info));
if (!p_name || !p_stmts || !new_node)
return NULL;
memset(new_node, NULL, sizeof(*new_node));
new_node->function_body = malloc(sizeof(node_info));
if (!new_node->function_body)
return NULL;
memset(new_node->function_body, NULL, sizeof(*new_node->function_body));
new_node->operation = FUNCTION_OPERATION;
new_node->operation_type.func = FUNCTION;
new_node->name = p_name;
new_node->next = NULL;
new_node->function_body->statement_list = p_stmts;
return new_node;
}
/*
Author: xerox
Update: 1/20/2020
create a function call given the name
TODO add scope.
*/
static node_info *create_function_call(char *p_name)
{
node_info *new_node = malloc(sizeof(node_info));
if (!new_node || !p_name)
return NULL;
memset(new_node, NULL, sizeof(*new_node));
new_node->operation = FUNCTION_OPERATION;
new_node->operation_type.func = FUNCTION_CALL;
new_node->name = p_name;
new_node->next = NULL;
return new_node;
}
/*
Author: xerox
Update: 1/20/2020
create compound statement given statement list and head of linked list.
*/
static node_info *create_compound_statement(node_info *new_statement_list, node_info *statement_head)
{
if (!new_statement_list)
return NULL;
if(!statement_head)
{
statement_head = malloc(sizeof(node_info));
node_info* new_node = malloc(sizeof(node_info));
if (!new_node || !statement_head)
return NULL;
memset(statement_head, NULL, sizeof(*statement_head));
memset(new_node, NULL, sizeof(*new_node));
statement_head->statement_list = malloc(sizeof(node_info));
if (!statement_head->statement_list)
return NULL;
memset(statement_head->statement_list, NULL,
sizeof(*statement_head->statement_list));
statement_head->operation = EXEC_STMT_LIST_OPERATION;
statement_head->statement_list->operation = EXEC_STMT_LIST_OPERATION;
statement_head->statement_list->next = new_statement_list;
statement_head->statement_list->statement_list = NULL;
}
else
{
node_info *p_temp_head = statement_head;
//TODO update with doubly linked list
while(p_temp_head->statement_list != NULL)
p_temp_head = p_temp_head->statement_list;
p_temp_head->statement_list = malloc(sizeof(node_info));
if (!p_temp_head->statement_list)
return NULL;
memset(p_temp_head->statement_list, NULL, sizeof(*p_temp_head->statement_list));
p_temp_head->operation = EXEC_STMT_LIST_OPERATION;
p_temp_head->statement_list->operation = EXEC_STMT_LIST_OPERATION;
p_temp_head->statement_list->next = new_statement_list;
p_temp_head->statement_list->statement_list = NULL;
}
return statement_head;
}
/*
Author: xerox
Update: 1/20/2020
add to compound statement given new statement and head of statement,
*/
static node_info* add_to_compound_statement(node_info* new_statement, node_info* statement_head)
{
if (!new_statement || !statement_head)
return NULL;
node_info* p_head_tmp = statement_head;
while (p_head_tmp->statement_list)
p_head_tmp = p_head_tmp->statement_list;
while (p_head_tmp->next)
p_head_tmp = p_head_tmp->next;
p_head_tmp->next = malloc(sizeof(node_info));
p_head_tmp->next = new_statement;
return statement_head;
}
#endif

@ -0,0 +1,11 @@
#ifndef FUNCTIONS
#define FUNCTIONS
#include "../types.h"
#include "../linked_list/linked_list.h"
#include "../linked_list/linked_list.c"
node_info *create_function(char *p_name, node_info *p_stmts);
node_info *create_function_call(char *p_name);
node_info *create_compound_statement(node_info *new_statement_list, node_info *statement_head);
node_info* add_to_compound_statement(node_info* new_statement, node_info* statement_head);
#endif

@ -0,0 +1,190 @@
#ifndef MAP_C
#define MAP_C
#include <stdlib.h>
#include <string.h>
#include "map.h"
struct map_node_t {
unsigned hash;
void *value;
map_node_t *next;
/* char key[]; */
/* char value[]; */
};
static unsigned map_hash(const char *str) {
unsigned hash = 5381;
while (*str) {
hash = ((hash << 5) + hash) ^ *str++;
}
return hash;
}
static map_node_t *map_newnode(const char *key, void *value, int vsize) {
map_node_t *node;
int ksize = strlen(key) + 1;
int voffset = ksize + ((sizeof(void*) - ksize) % sizeof(void*));
node = malloc(sizeof(*node) + voffset + vsize);
if (!node) return NULL;
memcpy(node + 1, key, ksize);
node->hash = map_hash(key);
node->value = ((char*) (node + 1)) + voffset;
memcpy(node->value, value, vsize);
return node;
}
static int map_bucketidx(map_base_t *m, unsigned hash) {
/* If the implementation is changed to allow a non-power-of-2 bucket count,
* the line below should be changed to use mod instead of AND */
return hash & (m->nbuckets - 1);
}
static void map_addnode(map_base_t *m, map_node_t *node) {
int n = map_bucketidx(m, node->hash);
node->next = m->buckets[n];
m->buckets[n] = node;
}
static int map_resize(map_base_t *m, int nbuckets) {
map_node_t *nodes, *node, *next;
map_node_t **buckets;
int i;
/* Chain all nodes together */
nodes = NULL;
i = m->nbuckets;
while (i--) {
node = (m->buckets)[i];
while (node) {
next = node->next;
node->next = nodes;
nodes = node;
node = next;
}
}
/* Reset buckets */
buckets = realloc(m->buckets, sizeof(*m->buckets) * nbuckets);
if (buckets != NULL) {
m->buckets = buckets;
m->nbuckets = nbuckets;
}
if (m->buckets) {
memset(m->buckets, 0, sizeof(*m->buckets) * m->nbuckets);
/* Re-add nodes to buckets */
node = nodes;
while (node) {
next = node->next;
map_addnode(m, node);
node = next;
}
}
/* Return error code if realloc() failed */
return (buckets == NULL) ? -1 : 0;
}
static map_node_t **map_getref(map_base_t *m, const char *key) {
unsigned hash = map_hash(key);
map_node_t **next;
if (m->nbuckets > 0) {
next = &m->buckets[map_bucketidx(m, hash)];
while (*next) {
if ((*next)->hash == hash && !strcmp((char*) (*next + 1), key)) {
return next;
}
next = &(*next)->next;
}
}
return NULL;
}
void map_deinit_(map_base_t *m) {
map_node_t *next, *node;
int i;
i = m->nbuckets;
while (i--) {
node = m->buckets[i];
while (node) {
next = node->next;
free(node);
node = next;
}
}
free(m->buckets);
}
void *map_get_(map_base_t *m, const char *key) {
map_node_t **next = map_getref(m, key);
return next ? (*next)->value : NULL;
}
int map_set_(map_base_t *m, const char *key, void *value, int vsize) {
int n, err;
map_node_t **next, *node;
/* Find & replace existing node */
next = map_getref(m, key);
if (next) {
memcpy((*next)->value, value, vsize);
return 0;
}
/* Add new node */
node = map_newnode(key, value, vsize);
if (node == NULL) goto fail;
if (m->nnodes >= m->nbuckets) {
n = (m->nbuckets > 0) ? (m->nbuckets << 1) : 1;
err = map_resize(m, n);
if (err) goto fail;
}
map_addnode(m, node);
m->nnodes++;
return 0;
fail:
if (node) free(node);
return -1;
}
void map_remove_(map_base_t *m, const char *key) {
map_node_t *node;
map_node_t **next = map_getref(m, key);
if (next) {
node = *next;
*next = (*next)->next;
free(node);
m->nnodes--;
}
}
map_iter_t map_iter_(void) {
map_iter_t iter;
iter.bucketidx = -1;
iter.node = NULL;
return iter;
}
const char *map_next_(map_base_t *m, map_iter_t *iter) {
if (iter->node) {
iter->node = iter->node->next;
if (iter->node == NULL) goto nextBucket;
} else {
nextBucket:
do {
if (++iter->bucketidx >= m->nbuckets) {
return NULL;
}
iter->node = m->buckets[iter->bucketidx];
} while (iter->node == NULL);
}
return (char*) (iter->node + 1);
}
#endif

@ -0,0 +1,77 @@
/**
* Copyright (c) 2014 rxi
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MIT license. See LICENSE for details.
*/
#ifndef MAP_H
#define MAP_H
#include <string.h>
#define MAP_VERSION "0.1.0"
struct map_node_t;
typedef struct map_node_t map_node_t;
typedef struct {
map_node_t **buckets;
unsigned nbuckets, nnodes;
} map_base_t;
typedef struct {
unsigned bucketidx;
map_node_t *node;
} map_iter_t;
#define map_t(T)\
struct { map_base_t base; T *ref; T tmp; }
#define map_init(m)\
memset(m, 0, sizeof(*(m)))
#define map_deinit(m)\
map_deinit_(&(m)->base)
#define map_get(m, key)\
( (m)->ref = map_get_(&(m)->base, key) )
#define map_set(m, key, value)\
( (m)->tmp = (value),\
map_set_(&(m)->base, key, &(m)->tmp, sizeof((m)->tmp)) )
#define map_remove(m, key)\
map_remove_(&(m)->base, key)
#define map_iter(m)\
map_iter_()
#define map_next(m, iter)\
map_next_(&(m)->base, iter)
void map_deinit_(map_base_t *m);
void *map_get_(map_base_t *m, const char *key);
int map_set_(map_base_t *m, const char *key, void *value, int vsize);
void map_remove_(map_base_t *m, const char *key);
map_iter_t map_iter_(void);
const char *map_next_(map_base_t *m, map_iter_t *iter);
typedef map_t(void*) map_void_t;
typedef map_t(char*) map_str_t;
typedef map_t(int) map_int_t;
typedef map_t(char) map_char_t;
typedef map_t(float) map_float_t;
typedef map_t(double) map_double_t;
#endif

@ -0,0 +1 @@
sudo apt install flex bison

@ -0,0 +1,87 @@
#ifndef LINKED_LIST_C
#define LINKED_LIST_C
#include "linked_list.h"
/*
Author: xerox
Update: 1/20/2020
free's linked list.
*/
static void free_linked_list(node_info *p_list)
{
if (!p_list)
return;
node_info* temp;
while (p_list->next)
{
temp = p_list;
p_list = p_list->next;
free(temp);
}
}
/*
Author: xerox
Update: 1/20/2020
updates linked list.
*/
static node_info *copy_linked_list(node_info *p_list)
{
node_info* new_list = malloc(sizeof(node_info));
if (!new_list || !p_list)
return NULL;
new_list->next = NULL;
node_info *copy_list = new_list;
//TODO update with doubly linked list
while(p_list->next)
{
p_list = p_list->next;
copy_list->next = p_list;
}
return new_list;
}
/*
Author: xerox
Update: 1/20/2020
append to linked list.
*/
static void linked_list_append(node_info* p_head, node_info* new_node)
{
if (!p_head || !new_node)
return;
node_info* p_head_temp = p_head;
while (p_head->next)
p_head_temp = p_head_temp->next;
p_head->next = NULL; //sanity check
p_head_temp->next = p_head;
}
/*
Author: xerox
Update: 1/20/2020
remove link from linked list.
*/
static bool linked_list_remove(node_info* p_head, node_info* delete_node)
{
if (!p_head || !delete_node)
return false;
node_info* p_head_temp = p_head;
while (p_head_temp->next)
{
if (p_head_temp->next == delete_node)
{
p_head_temp->next = delete_node->next;
free(delete_node);
return true;
}
}
return false;
}
#endif

@ -0,0 +1,9 @@
#ifndef LINKED_LIST_H
#define LINKED_LIST_H
#include "../types.h"
void free_linked_list(node_info *p_list);
node_info *copy_linked_list(node_info *p_list);
void linked_list_append(node_info* p_head, node_info* new_node);
bool linked_list_remove(node_info* p_head, node_info* delete_node);
#endif

@ -0,0 +1,20 @@
#include "logic.h"
/*
Author: xerox
Date: 1/19/2020
creates logic given type, statement list to execute, and variable name for condition.
*/
static logic* create_logic(logic_type type, node_info* stmt_list, char* var_name)
{
logic* new_logic = malloc(sizeof(logic));
if (!new_logic || !stmt_list || !var_name)
return NULL;
memset(new_logic, NULL, sizeof(*new_logic));
new_logic->type = type;
new_logic->condition_var = var_name;
new_logic->stmt_list = stmt_list;
return new_logic;
}

@ -0,0 +1,5 @@
#ifndef LOGIC_H
#define LOGIC_H
#include "../types.h"
logic* create_logic(logic_type type, node_info* stmt_list, char* var_name);
#endif

@ -0,0 +1,3 @@
lex deon.l
yacc -d deon.y
gcc lex.yy.c y.tab.c -o deon

@ -0,0 +1,257 @@
#ifndef PARSER_C
#define PARSER_C
#include "parser.h"
/*
Author: xerox
Updated: 1/19/2020
create variable given name, value, and type.
*/
static node_info* create_variable_const(char* p_name, void* value, variable_type var_type)
{
node_info* new_node = malloc(sizeof(*new_node));
if (!new_node)
return NULL;
memset(new_node, NULL, sizeof(*new_node));
variable* new_var = make_variable(p_name, value, var_type);
if (!new_var)
return NULL;
new_node->assignment = (assignment_operation*)malloc(sizeof(assignment_operation));
if (!new_node->assignment)
return NULL;
memset(new_node->assignment, NULL, sizeof(*new_node->assignment));
new_node->operation = ASSIGNMENT_OPERATION;
new_node->operation_type.assignment = ASSIGN_FROM_CONST;
new_node->assignment->var = new_var;
return new_node;
}
/*
Author: xerox
Updated: 1/20/2020
Move value from one variable to another.
*/
static node_info* move_value(char* to, char* from)
{
node_info* new_node = (node_info *)malloc(sizeof(node_info));
if (!from || !new_node || !to)
return NULL;
memset(new_node, NULL, sizeof(*new_node));
new_node->assignment = (assignment_operation*)malloc(sizeof(*new_node->assignment));
if (!new_node->assignment)
return NULL;
memset(new_node->assignment, NULL, sizeof(*new_node->assignment));
new_node->operation = ASSIGNMENT_OPERATION;
new_node->operation_type.assignment = ASSIGN_FROM_VAR;
new_node->assignment->from = from;
new_node->assignment->to = to;
return new_node;
}
/*
Author: xerox
Updated: 1/19/2020
create logic node (logical expression)
*/
static node_info* create_logic_node(logic* logic_expr)
{
node_info* new_node = malloc(sizeof(node_info));
if (!new_node || !logic_expr)
return NULL;
memset(new_node, NULL, sizeof(*new_node));
new_node->operation = LOGIC_OPERATION;
new_node->logical_expr = logic_expr;
return new_node;
}
/*
Author: xerox
Updated: 1/20/2020
Executes a statment.
@param nodeInfo statement to be executed
@return void.
*/
static void exec_stmt(node_info *exec_node)
{
if (!exec_node)
return;
switch (exec_node->operation)
{
case ASSIGNMENT_OPERATION:
switch (exec_node->operation_type.assignment)
{
case ASSIGN_FROM_CONST:
add_var(exec_node->assignment->var->name, exec_node->assignment->var->value, _var_map);
break;
case ASSIGN_FROM_VAR:
add_var(exec_node->assignment->to,
get_value(exec_node->assignment->from, _var_map), _var_map);
break;
default:
;
#if DEON_DEBUGGING
printf("[error] unkown assignment operation: 0x%x", exec_node->operation_type.assignment);
#endif
}
break;
case LOGIC_OPERATION:
{
switch (exec_node->logical_expr->type)
{
case IF_LOGIC:
{
variable_values* p_var_values = get_value(exec_node->logical_expr->condition_var, _var_map);
if (!p_var_values)
return;
if (*(unsigned char*)p_var_values->data_ptr)
exec_stmt(exec_node->logical_expr->stmt_list);
break;
}
case WHILE_LOGIC:
{
variable_values* p_var_values = get_value(exec_node->logical_expr->condition_var, _var_map);
if (!p_var_values)
return;
while (*(unsigned char*)p_var_values->data_ptr)
{
exec_stmt(exec_node->logical_expr->stmt_list);
p_var_values = get_value(exec_node->logical_expr->condition_var, _var_map);
}
break;
}
default:
;
#if DEON_DEBUGGING
printf("[error] unknown logic operation\n");
#endif
}
}
// execute statement list.
case EXEC_STMT_LIST_OPERATION:
{
if(exec_node->statement_list)
exec_node = exec_node->statement_list;
while (exec_node->next)
{
exec_node = exec_node->next;
exec_stmt(exec_node);
}
break;
}
// print statement
case PRINT_OPERATION:
{
switch (exec_node->operation_type.print)
{
case PRINT_CONSTANT:
{
switch (exec_node->print_expr->type)
{
case VAR_STRING:
printf("%s\n", (char*)exec_node->print_expr->value);
break;
case VAR_INT:
printf("%d\n", *(int*)exec_node->print_expr->value);
break;
case VAR_BYTE:
printf("%c\n", *(char*)exec_node->print_expr->value);
break;
case VAR_DOUBLE:
printf("%f\n", *(double*)exec_node->print_expr->value);
break;
case VAR_VOID: //TODO add void variable type
break;
default:
;
#if DEON_DEBUGGING
printf("[error] unable to print variable of type: 0x%x\n", exec_node->print_expr->type);
#endif
}
break;
}
case PRINT_VARIABLE:
{
variable_values* p_var = get_value(exec_node->var->name, _var_map);
switch (p_var->type)
{
case VAR_STRING:
printf("%s\n", (char*)p_var->data_ptr);
break;
case VAR_INT:
printf("%d\n", *(int*)p_var->data_ptr);
break;
case VAR_BYTE:
printf("%c\n", *(char*)p_var->data_ptr);
break;
case VAR_DOUBLE:
printf("%f\n", *(double*)p_var->data_ptr);
break;
case VAR_VOID: //TODO add void variable type
break;
default:
;
#if DEON_DEBUGGING
printf("[error] unable to print variable of type: 0x%x\n", p_var->type);
#endif
}
break;
}
default:
;
#if DEON_DEBUGGING
printf("[error] unknown print type: 0x%x\n", exec_node->operation_type.print);
#endif
}
break;
}
case FUNCTION_OPERATION:
{
switch (exec_node->operation_type.func)
{
case FUNCTION_CALL:
{
node_info* _stmts = *map_get(&*((map_void_t*)_function_list), exec_node->name);
_stmts = _stmts->statement_list;
while (_stmts->statement_list)
{
_stmts = _stmts->statement_list;
exec_stmt(_stmts);
}
break;
}
case FUNCTION:
{
if (!_function_list)
{
_function_list = malloc(sizeof(map_void_t));
map_init(_function_list);
map_set(_function_list, exec_node->name, exec_node->function_body);
}
else //else we dont malloc, we just put the function inside of the hashmap.
map_set(_function_list, exec_node->name, exec_node->function_body);
break;
}
default:
;
#if DEON_DEBUGGING
printf("[error] unknown function operation: 0x%x\n", exec_node->operation_type.func);
#endif
}
break;
}
default:
;
#if DEON_DEBUGGING
printf("[error] unknown operation: 0x%x\n", exec_node->operation);
#endif
}
}
#endif

@ -0,0 +1,9 @@
#ifndef PARSER_H
#define PARSER_H
#include "../types.h"
#include "../vars/vars.h"
node_info* create_variable_const(char* p_name, void* value, variable_type var_type);
node_info* move_value(char* to, char* from);
node_info* create_logic_node(logic* logic_expr);
void exec_stmt(node_info *exec_node);
#endif

@ -0,0 +1,54 @@
#ifndef PRINT_C
#define PRINT_C
#include "print.h"
/*
Author: xerox
Updated: 1/20/2020
creates a print statement given variable type and value.
*/
static node_info *create_print_statement(variable_type operation, void* value)
{
node_info* new_print_stmt = (node_info*)malloc(sizeof(node_info));
print* new_print = malloc(sizeof(print));
if (!new_print_stmt || !new_print)
return NULL;
memset(new_print_stmt, NULL, sizeof(*new_print_stmt));
memset(new_print, NULL, sizeof(*new_print));
new_print_stmt->operation = PRINT_OPERATION;
new_print_stmt->operation_type.print = PRINT_CONSTANT;
new_print->type = operation;
new_print->value = value;
new_print_stmt->print_expr = new_print;
new_print_stmt->next = NULL;
return new_print_stmt;
}
/*
Author: xerox
Updated: 1/19/2020
create print variable from variable name.
*/
static node_info* create_print_variable(char* var_name)
{
node_info* new_print_stmt = (node_info*)malloc(sizeof(node_info));
if (!new_print_stmt || !var_name)
return NULL;
memset(new_print_stmt, NULL, sizeof(*new_print_stmt));
new_print_stmt->var = malloc(sizeof(variable));
if (!new_print_stmt->var)
return NULL;
memset(new_print_stmt->var, NULL, sizeof(*new_print_stmt->var));
new_print_stmt->operation = PRINT_OPERATION;
new_print_stmt->operation_type.print = PRINT_VARIABLE;
new_print_stmt->var->name = var_name;
new_print_stmt->next = NULL;
return new_print_stmt;
}
#endif

@ -0,0 +1,6 @@
#ifndef PRINT_H
#define PRINT_H
#include "../types.h"
node_info* create_print_statement(variable_type operation, void* value);
node_info* create_print_variable(char* var_name);
#endif

@ -0,0 +1,128 @@
#ifndef INCLUDE_H
#define INCLUDE_H
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include "hashmap/map.h"
#define DEON_DEBUGGING 0
bool _DEON_DEBUG;
//--- different variable values
typedef enum _variable_type
{
VAR_INT,
VAR_SHORT,
VAR_BYTE,
VAR_DOUBLE,
VAR_STRING,
VAR_VOID
} variable_type;
//--- different function operations
typedef enum _function_type
{
FUNCTION,
FUNCTION_CALL,
} function_type;
//--- different print operations
typedef enum _print_type
{
PRINT_VARIABLE,
PRINT_CONSTANT
} print_type;
//--- different logic types
typedef enum _logic_type
{
IF_LOGIC,
WHILE_LOGIC
} logic_type;
typedef enum _assignment_type
{
ASSIGN_FROM_VAR,
ASSIGN_FROM_CONST
} assignment_type;
//--- all operations in the language
typedef enum _operation
{
ASSIGNMENT_OPERATION,
LOGIC_OPERATION,
EXEC_STMT_LIST_OPERATION,
PRINT_OPERATION,
FUNCTION_OPERATION,
};
//--- variable value details
typedef struct _variable_values
{
variable_type type;
void* data_ptr;
} variable_values;
//--- variable details
typedef struct _variable
{
char *name;
variable_values *value;
struct variable *next;
} variable;
//--- print data
typedef struct _print
{
enum _variable_type type;
void* value;
} print;
//--- assignment data
typedef struct _assignment_operation
{
char* from;
char* to;
variable* var;
}assignment_operation;
//--- logic operation data
typedef struct _logic
{
logic_type type;
char* condition_var;
struct node_info* stmt_list;
} logic;
//--- struct that brings it all together
typedef struct node_info
{
//--- node operation.
enum _operation operation;
//--- sub operations.
union _operation_type
{
logic_type logic;
function_type func;
print_type print;
assignment_type assignment;
} operation_type;
char *name;
print* print_expr;
logic* logical_expr;
assignment_operation* assignment;
variable* var;
struct node_info *next;
struct node_info *function_body;
struct node_info *statement_list;
struct node_info *new_scope;
struct map_void_t *var_map;
} node_info;
//--- globals
map_void_t* _var_map;
node_info* _temp_statement_head;
map_void_t* _function_list;
#endif

@ -0,0 +1,104 @@
#ifndef VARS_C
#define VARS_C
#include "vars.h"
/*
Author: xerox
Date: 1/20/2020
add var to hashmap of variables.
*/
static void add_var(char *p_name, variable_values *p_values, map_void_t* p_var_map)
{
if (!p_name || !p_values)
return;
map_set(p_var_map, p_name, p_values);
}
/*
Author: xerox
Date: 1/20/2020
get value given name and hashmap.
*/
static variable_values* get_value(char *p_name, map_void_t* p_var_map)
{
if (!p_name)
return NULL;
return *map_get(&*((map_void_t* ) p_var_map), p_name);
}
/*
Author: xerox
Date: 1/20/2020
makes a variable struct and define it.
*/
static variable* make_variable(char *p_name, void* value, variable_type var_type)
{
variable *new_var = malloc(sizeof(variable));
variable_values *new_value = malloc(sizeof(variable_values));
if (!new_var || !new_value || !p_name || !value)
return NULL;
memset(new_var, NULL, sizeof(*new_var));
memset(new_value, NULL, sizeof(*new_value));
new_value->type = var_type;
new_value->data_ptr = value;
new_var->name = p_name;
new_var->value = new_value;
return new_var;
}
/*
Author: xerox
Date: 1/20/2020
allocate memory for values that are 8 bytes or less.
*/
static void* alloc_value(void* value, variable_type var_type)
{
switch (var_type)
{
case VAR_INT:
{
int* p_int = (int*)malloc(sizeof(int));
if (!p_int)
return NULL;
memset(p_int, NULL, sizeof(*p_int));
*p_int = *(int*)value;
return p_int;
}
case VAR_SHORT:
{
short* p_short = (short*)malloc(sizeof(short));
if (!p_short)
return NULL;
memset(p_short, NULL, sizeof(*p_short));
*p_short = *(short*)value;
return p_short;
}
case VAR_BYTE:
{
char* p_char = malloc(sizeof(char));
if (!p_char)
return NULL;
memset(p_char, NULL, sizeof(*p_char));
*p_char = *(char*)value;
return p_char;
}
case VAR_DOUBLE:
{
double* p_double = malloc(sizeof(double));
if (!p_double)
return NULL;
memset(p_double, NULL, sizeof(*p_double));
*p_double = *(double*)value;
return p_double;
}
default:
return NULL;
}
}
#endif

@ -0,0 +1,8 @@
#ifndef VARS_H
#define VARS_H
#include "../types.h"
void add_var(char* name, variable_values* values, map_void_t* p_var_map);
variable* make_variable(char* p_name, void* value, variable_type var_type);
variable_values* get_value(char* p_name, map_void_t* p_var_map);
void* alloc_value(void* value, variable_type var_type);
#endif

Binary file not shown.

@ -0,0 +1,46 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29519.181
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "deon", "deon\deon.vcxproj", "{B08E2E4F-D8D8-4089-AD3B-6AE42D6F0DBD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
arm|ARM = arm|ARM
arm|x64 = arm|x64
arm|x86 = arm|x86
Debug|ARM = Debug|ARM
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|ARM = Release|ARM
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B08E2E4F-D8D8-4089-AD3B-6AE42D6F0DBD}.arm|ARM.ActiveCfg = Debug|ARM
{B08E2E4F-D8D8-4089-AD3B-6AE42D6F0DBD}.arm|ARM.Build.0 = Debug|ARM
{B08E2E4F-D8D8-4089-AD3B-6AE42D6F0DBD}.arm|x64.ActiveCfg = Release|x64
{B08E2E4F-D8D8-4089-AD3B-6AE42D6F0DBD}.arm|x64.Build.0 = Release|x64
{B08E2E4F-D8D8-4089-AD3B-6AE42D6F0DBD}.arm|x86.ActiveCfg = Release|Win32
{B08E2E4F-D8D8-4089-AD3B-6AE42D6F0DBD}.arm|x86.Build.0 = Release|Win32
{B08E2E4F-D8D8-4089-AD3B-6AE42D6F0DBD}.Debug|ARM.ActiveCfg = Debug|ARM
{B08E2E4F-D8D8-4089-AD3B-6AE42D6F0DBD}.Debug|ARM.Build.0 = Debug|ARM
{B08E2E4F-D8D8-4089-AD3B-6AE42D6F0DBD}.Debug|x64.ActiveCfg = Debug|x64
{B08E2E4F-D8D8-4089-AD3B-6AE42D6F0DBD}.Debug|x64.Build.0 = Debug|x64
{B08E2E4F-D8D8-4089-AD3B-6AE42D6F0DBD}.Debug|x86.ActiveCfg = Debug|Win32
{B08E2E4F-D8D8-4089-AD3B-6AE42D6F0DBD}.Debug|x86.Build.0 = Debug|Win32
{B08E2E4F-D8D8-4089-AD3B-6AE42D6F0DBD}.Release|ARM.ActiveCfg = Release|ARM
{B08E2E4F-D8D8-4089-AD3B-6AE42D6F0DBD}.Release|ARM.Build.0 = Release|ARM
{B08E2E4F-D8D8-4089-AD3B-6AE42D6F0DBD}.Release|x64.ActiveCfg = Release|x64
{B08E2E4F-D8D8-4089-AD3B-6AE42D6F0DBD}.Release|x64.Build.0 = Release|x64
{B08E2E4F-D8D8-4089-AD3B-6AE42D6F0DBD}.Release|x86.ActiveCfg = Release|Win32
{B08E2E4F-D8D8-4089-AD3B-6AE42D6F0DBD}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E72D3DDB-12F2-42F7-A410-068392F5951A}
EndGlobalSection
EndGlobal

@ -0,0 +1,84 @@
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "types.h"
#include "y.tab.h"
void yyerror(char *);
extern YYSTYPE yylval;
extern FILE *yyin;
int yylineno;
%}
%%
\/\*.*?\*\/ { ; // comment }
-?[0-9]+ { yylval.int_num = atoi(yytext); return INTEGER; }
\'[ -~]\' { yylval.byte_num = yytext[1]; return CHAR; }
[-()<>=+*/:;,%{}\[\]] { return *yytext; }
"if" { return IF; }
"else" { return ELSE; }
"print" { return PRINT_TOKEN; }
"string" { return KEYWORD_S; }
"while" { return WHILE; }
"int" { return KEYWORD_I; }
"def" { return DEF;}
"call" { return CALL; }
"char" { return KEYWORD_C; }
"++" { return INCREASE; }
"--" { return DECREASE; }
\"(\\.|[^"\\])*\" { yytext++; yytext[strlen(yytext)-1] = 0; yylval.str_ptr = strdup(yytext); return STRING; }
[a-zA-Z0-9_]+ { yylval.str_ptr = strdup(yytext); return VARNAME; }
-?[0-9]*\.[0-9]+ { yylval.double_num = atof(yytext); return DOUBLEVAR; }
"\n" { yylineno++; }
[ ?\t\n\r]
. printf("invalid character on line %d, '%s'\n", yylineno, yytext);
<<EOF>> { exit(0); }
%%
int yywrap(void) {
return 1;
}
int main(int argc, char* argv[])
{
_var_map = malloc(sizeof(map_void_t));
map_init(_var_map);
_temp_statement_head = NULL;
_function_list = NULL;
FILE *fh;
if (argc > 1)
{
if (strcmp(argv[1],"help") == 0 || strcmp(argv[1],"-help") == 0
|| strcmp(argv[1],"--help") == 0 || strcmp(argv[1],"h") == 0
|| strcmp(argv[1],"-h") == 0)
{
printf("[ HELP ] put a file/path as the first flag.\n");
printf("[ HELP ] -h, -help, --help, help, h: Prints this.\n");
printf("[ HELP ] -d, d, -debug, debug: Enter REPL mode.\n");
}
else if (strcmp(argv[1],"-debug") == 0 || strcmp(argv[1],"-d") == 0
|| strcmp(argv[1],"d") == 0 || strcmp(argv[1],"debug") == 0)
{
_DEON_DEBUG = 1;
printf(">>> ");
yyparse();
}
else if (fh = fopen(argv[1], "r"))
{
yyin = fh;
yyparse();
fclose(fh);
}
else
{
printf("[ ERROR ] please enter a correct command. try --help\n");
fclose(fh);
}
} else
printf("[ ERROR ] missing input file. Try --help?\n");
return 0;
}

@ -0,0 +1,249 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="functions\functions.h" />
<ClInclude Include="hashmap\map.h" />
<ClInclude Include="linked_list\linked_list.h" />
<ClInclude Include="logic\logic.h" />
<ClInclude Include="parser\parser.h" />
<ClInclude Include="print\print.h" />
<ClInclude Include="types.h" />
<ClInclude Include="vars\vars.h" />
<ClInclude Include="y.tab.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="functions\functions.c" />
<ClCompile Include="hashmap\map.c" />
<ClCompile Include="lex.yy.c" />
<ClCompile Include="linked_list\linked_list.c" />
<ClCompile Include="logic\logic.c" />
<ClCompile Include="parser\parser.c" />
<ClCompile Include="print\print.c" />
<ClCompile Include="vars\vars.c" />
<ClCompile Include="y.tab.c" />
</ItemGroup>
<ItemGroup>
<None Include="deon.l" />
<None Include="deon.y" />
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<ProjectGuid>{B08E2E4F-D8D8-4089-AD3B-6AE42D6F0DBD}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>deon</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<SpectreMitigation>false</SpectreMitigation>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<SpectreMitigation>false</SpectreMitigation>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<SpectreMitigation>false</SpectreMitigation>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<SpectreMitigation>false</SpectreMitigation>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<SpectreMitigation>false</SpectreMitigation>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<SpectreMitigation>false</SpectreMitigation>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

@ -0,0 +1,125 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Source Files\vars">
<UniqueIdentifier>{e714c06a-61ed-402f-aba1-b117816214ef}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\print">
<UniqueIdentifier>{09c9fb63-23fb-4550-a04d-e80dfa427087}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\parser">
<UniqueIdentifier>{f02fae95-5469-4a66-965c-ab6e34944acc}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\logic">
<UniqueIdentifier>{dfbeb42c-97f8-442c-9e2b-b06bddbaf130}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\linked_list">
<UniqueIdentifier>{cc02b417-9e26-4516-ad85-0d4635c42a8a}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\hashmap">
<UniqueIdentifier>{aa53f4f6-6c52-40a3-83ca-a40248cee33f}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\functions">
<UniqueIdentifier>{95c73e4f-29a8-422c-b888-7d34a098475a}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\logic">
<UniqueIdentifier>{d3b81bd9-e566-495b-9a64-4fa4338c0edc}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\linked_list">
<UniqueIdentifier>{0b0b872d-e26d-42e7-b04b-6dd4ca4d2b8a}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\hashmap">
<UniqueIdentifier>{a36a6e3d-0e8f-4b31-8704-d2f9cc2e8dc6}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\functions">
<UniqueIdentifier>{74db9698-20f2-4845-a492-79864f55ce95}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\parser">
<UniqueIdentifier>{f9162cac-d61b-4569-8d3f-50c3340ecfb7}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\print">
<UniqueIdentifier>{b8feaf5e-1191-47dd-9c30-65893043cf41}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\vars">
<UniqueIdentifier>{8d996674-ea54-4b0c-a572-099444cf65a3}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="logic\logic.h">
<Filter>Header Files\logic</Filter>
</ClInclude>
<ClInclude Include="linked_list\linked_list.h">
<Filter>Header Files\linked_list</Filter>
</ClInclude>
<ClInclude Include="hashmap\map.h">
<Filter>Header Files\hashmap</Filter>
</ClInclude>
<ClInclude Include="functions\functions.h">
<Filter>Header Files\functions</Filter>
</ClInclude>
<ClInclude Include="vars\vars.h">
<Filter>Header Files\vars</Filter>
</ClInclude>
<ClInclude Include="print\print.h">
<Filter>Header Files\print</Filter>
</ClInclude>
<ClInclude Include="parser\parser.h">
<Filter>Header Files\parser</Filter>
</ClInclude>
<ClInclude Include="types.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="y.tab.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="logic\logic.c">
<Filter>Source Files\logic</Filter>
</ClCompile>
<ClCompile Include="linked_list\linked_list.c">
<Filter>Source Files\linked_list</Filter>
</ClCompile>
<ClCompile Include="hashmap\map.c">
<Filter>Source Files\hashmap</Filter>
</ClCompile>
<ClCompile Include="functions\functions.c">
<Filter>Source Files\functions</Filter>
</ClCompile>
<ClCompile Include="parser\parser.c">
<Filter>Source Files\parser</Filter>
</ClCompile>
<ClCompile Include="print\print.c">
<Filter>Source Files\print</Filter>
</ClCompile>
<ClCompile Include="vars\vars.c">
<Filter>Source Files\vars</Filter>
</ClCompile>
<ClCompile Include="lex.yy.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="y.tab.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="deon.l">
<Filter>Source Files</Filter>
</None>
<None Include="deon.y">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
</Project>

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerCommandArguments>-d</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LocalDebuggerCommandArguments>-d</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerCommandArguments>-d</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<LocalDebuggerCommandArguments>-d</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LocalDebuggerCommandArguments>-d</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<LocalDebuggerCommandArguments>-d</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
</Project>

@ -0,0 +1,119 @@
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "types.h"
#include "parser/parser.c"
#include "functions/functions.c"
#include "logic/logic.c"
#include "print/print.c"
#include "vars/vars.c"
int yylex(void);
void yyerror(char *);
extern int yylineno;
%}
/* doing these before multiplication and division because they have a lower presidence */
%left '<' '>'
%left '+' '-'
/* doing this last so they have a higher presidence */
%left '*' '/' '%'
%union {
char* str_ptr;
int int_num;
unsigned uint_num;
char byte_num;
double double_num;
float float_num;
struct node_info *node_ptr;
}
%token INCREASE DECREASE PRINT_TOKEN IF END KEYWORD_S KEYWORD_I KEYWORD_C QUOTE ELSE WHILE DEF CALL
%token <int_num> INTEGER
%token <str_ptr> STRING VARNAME
%token <byte_num> CHAR
%token <double_num> DOUBLEVAR
%token <float_num> FLOAT_NUM
%type <int_num> EXPR
%type <node_ptr> STMT PRINT VARIABLE FUNC STMT_LIST LOGIC
%%
PROGRAM:
MAIN '\n'
|
;
MAIN:
MAIN FUNC ';' { if (_DEON_DEBUG == true ) { printf(">>> "); exec_stmt($2); } else { exec_stmt($2); } }
|
;
FUNC:
DEF VARNAME ':' '{' STMT_LIST '}' { $$ = create_function($2, $5); }
| CALL VARNAME { $$ = create_function_call($2); }
;
STMT_LIST:
STMT ';' { $$ = create_compound_statement($1, _temp_statement_head); }
| STMT_LIST STMT ';' { $$ = add_to_compound_statement($2, $1); }
;
STMT:
VARIABLE { $$ = $1; }
| LOGIC { $$ = $1; }
| FUNC { $$ = $1; }
| PRINT_TOKEN '[' PRINT ']' { $$ = $3; }
| '{' STMT_LIST '}' { $$ = $2; }
;
LOGIC:
IF '[' VARNAME ']' ':' '{' STMT_LIST '}' { $$ = create_logic_node(create_logic(IF_LOGIC, $7, $3)); }
| WHILE '[' VARNAME ']' ':' '{' STMT_LIST '}' { $$ = create_logic_node(create_logic(WHILE_LOGIC, $7, $3)); }
;
VARIABLE:
VARNAME '=' STRING { $$ = create_variable_const($1, (void *) $3, VAR_STRING);}
| VARNAME '=' EXPR { $$ = create_variable_const($1, alloc_value(&$3, VAR_INT), VAR_INT);}
| VARNAME '=' CHAR { $$ = create_variable_const($1, alloc_value(&$3, VAR_BYTE), VAR_BYTE);}
| VARNAME '=' DOUBLEVAR { $$ = create_variable_const($1, alloc_value(&$3, VAR_DOUBLE), VAR_DOUBLE);}
| VARNAME '=' '{' STMT_LIST '}' { $$ = create_function($1, $4); }
| VARNAME '=' VARNAME { $$ = move_value($1, $3); }
;
EXPR:
INTEGER { $$ = $1; }
| EXPR '+' EXPR { $$ = $1 + $3; }
| EXPR '-' EXPR { $$ = $1 - $3; }
| EXPR '*' EXPR { $$ = $1 * $3; }
| EXPR '/' EXPR { $$ = $1 / $3; }
| EXPR '%' EXPR { $$ = $1 % $3; }
| EXPR '>' EXPR { if ($1 > $3) { $$ = 1; } else { $$ = 0;}}
| EXPR '<' EXPR { if ($1 < $3) { $$ = 1; } else { $$ = 0;}}
| INCREASE EXPR { $$ = $2 + 1; }
| EXPR INCREASE { $$ = $1 + 1; }
| DECREASE EXPR { $$ = $2 - 1; }
| EXPR DECREASE { $$ = $1 - 1; }
| '(' EXPR ')' { $$ = $2; }
;
PRINT:
VARNAME { $$ = create_print_variable($1); }
| EXPR { $$ = create_print_statement(VAR_INT, alloc_value(&$1, VAR_INT)); }
| STRING { $$ = create_print_statement(VAR_STRING, $1); }
;
%%
void yyerror(char *s)
{
fprintf(stderr, "Error on line %d, %s\n", yylineno, s);
}

@ -0,0 +1,125 @@
#ifndef FUNCTIONS_C
#define FUNCTIONC_C
#include "functions.h"
/*
Author: xerox
Update: 1/20/2020
create a function given the name of the function and the statements
*/
static node_info *create_function(char *p_name, node_info *p_stmts)
{
node_info *new_node = malloc(sizeof(node_info));
if (!p_name || !p_stmts || !new_node)
return NULL;
memset(new_node, NULL, sizeof(*new_node));
new_node->function_body = malloc(sizeof(node_info));
if (!new_node->function_body)
return NULL;
memset(new_node->function_body, NULL, sizeof(*new_node->function_body));
new_node->operation = FUNCTION_OPERATION;
new_node->operation_type.func = FUNCTION;
new_node->name = p_name;
new_node->next = NULL;
new_node->function_body->statement_list = p_stmts;
return new_node;
}
/*
Author: xerox
Update: 1/20/2020
create a function call given the name
TODO add scope.
*/
static node_info *create_function_call(char *p_name)
{
node_info *new_node = malloc(sizeof(node_info));
if (!new_node || !p_name)
return NULL;
memset(new_node, NULL, sizeof(*new_node));
new_node->operation = FUNCTION_OPERATION;
new_node->operation_type.func = FUNCTION_CALL;
new_node->name = p_name;
new_node->next = NULL;
return new_node;
}
/*
Author: xerox
Update: 1/20/2020
create compound statement given statement list and head of linked list.
*/
static node_info *create_compound_statement(node_info *new_statement_list, node_info *statement_head)
{
if (!new_statement_list)
return NULL;
if(!statement_head)
{
statement_head = malloc(sizeof(node_info));
node_info* new_node = malloc(sizeof(node_info));
if (!new_node || !statement_head)
return NULL;
memset(statement_head, NULL, sizeof(*statement_head));
memset(new_node, NULL, sizeof(*new_node));
statement_head->statement_list = malloc(sizeof(node_info));
if (!statement_head->statement_list)
return NULL;
memset(statement_head->statement_list, NULL,
sizeof(*statement_head->statement_list));
statement_head->operation = EXEC_STMT_LIST_OPERATION;
statement_head->statement_list->operation = EXEC_STMT_LIST_OPERATION;
statement_head->statement_list->next = new_statement_list;
statement_head->statement_list->statement_list = NULL;
}
else
{
node_info *p_temp_head = statement_head;
//TODO update with doubly linked list
while(p_temp_head->statement_list != NULL)
p_temp_head = p_temp_head->statement_list;
p_temp_head->statement_list = malloc(sizeof(node_info));
if (!p_temp_head->statement_list)
return NULL;
memset(p_temp_head->statement_list, NULL, sizeof(*p_temp_head->statement_list));
p_temp_head->operation = EXEC_STMT_LIST_OPERATION;
p_temp_head->statement_list->operation = EXEC_STMT_LIST_OPERATION;
p_temp_head->statement_list->next = new_statement_list;
p_temp_head->statement_list->statement_list = NULL;
}
return statement_head;
}
/*
Author: xerox
Update: 1/20/2020
add to compound statement given new statement and head of statement,
*/
static node_info* add_to_compound_statement(node_info* new_statement, node_info* statement_head)
{
if (!new_statement || !statement_head)
return NULL;
node_info* p_head_tmp = statement_head;
while (p_head_tmp->statement_list)
p_head_tmp = p_head_tmp->statement_list;
while (p_head_tmp->next)
p_head_tmp = p_head_tmp->next;
p_head_tmp->next = malloc(sizeof(node_info));
p_head_tmp->next = new_statement;
return statement_head;
}
#endif

@ -0,0 +1,11 @@
#ifndef FUNCTIONS
#define FUNCTIONS
#include "../types.h"
#include "../linked_list/linked_list.h"
#include "../linked_list/linked_list.c"
node_info *create_function(char *p_name, node_info *p_stmts);
node_info *create_function_call(char *p_name);
node_info *create_compound_statement(node_info *new_statement_list, node_info *statement_head);
node_info* add_to_compound_statement(node_info* new_statement, node_info* statement_head);
#endif

@ -0,0 +1,190 @@
#ifndef MAP_C
#define MAP_C
#include <stdlib.h>
#include <string.h>
#include "map.h"
struct map_node_t {
unsigned hash;
void *value;
map_node_t *next;
/* char key[]; */
/* char value[]; */
};
static unsigned map_hash(const char *str) {
unsigned hash = 5381;
while (*str) {
hash = ((hash << 5) + hash) ^ *str++;
}
return hash;
}
static map_node_t *map_newnode(const char *key, void *value, int vsize) {
map_node_t *node;
int ksize = strlen(key) + 1;
int voffset = ksize + ((sizeof(void*) - ksize) % sizeof(void*));
node = malloc(sizeof(*node) + voffset + vsize);
if (!node) return NULL;
memcpy(node + 1, key, ksize);
node->hash = map_hash(key);
node->value = ((char*) (node + 1)) + voffset;
memcpy(node->value, value, vsize);
return node;
}
static int map_bucketidx(map_base_t *m, unsigned hash) {
/* If the implementation is changed to allow a non-power-of-2 bucket count,
* the line below should be changed to use mod instead of AND */
return hash & (m->nbuckets - 1);
}
static void map_addnode(map_base_t *m, map_node_t *node) {
int n = map_bucketidx(m, node->hash);
node->next = m->buckets[n];
m->buckets[n] = node;
}
static int map_resize(map_base_t *m, int nbuckets) {
map_node_t *nodes, *node, *next;
map_node_t **buckets;
int i;
/* Chain all nodes together */
nodes = NULL;
i = m->nbuckets;
while (i--) {
node = (m->buckets)[i];
while (node) {
next = node->next;
node->next = nodes;
nodes = node;
node = next;
}
}
/* Reset buckets */
buckets = realloc(m->buckets, sizeof(*m->buckets) * nbuckets);
if (buckets != NULL) {
m->buckets = buckets;
m->nbuckets = nbuckets;
}
if (m->buckets) {
memset(m->buckets, 0, sizeof(*m->buckets) * m->nbuckets);
/* Re-add nodes to buckets */
node = nodes;
while (node) {
next = node->next;
map_addnode(m, node);
node = next;
}
}
/* Return error code if realloc() failed */
return (buckets == NULL) ? -1 : 0;
}
static map_node_t **map_getref(map_base_t *m, const char *key) {
unsigned hash = map_hash(key);
map_node_t **next;
if (m->nbuckets > 0) {
next = &m->buckets[map_bucketidx(m, hash)];
while (*next) {
if ((*next)->hash == hash && !strcmp((char*) (*next + 1), key)) {
return next;
}
next = &(*next)->next;
}
}
return NULL;
}
void map_deinit_(map_base_t *m) {
map_node_t *next, *node;
int i;
i = m->nbuckets;
while (i--) {
node = m->buckets[i];
while (node) {
next = node->next;
free(node);
node = next;
}
}
free(m->buckets);
}
void *map_get_(map_base_t *m, const char *key) {
map_node_t **next = map_getref(m, key);
return next ? (*next)->value : NULL;
}
int map_set_(map_base_t *m, const char *key, void *value, int vsize) {
int n, err;
map_node_t **next, *node;
/* Find & replace existing node */
next = map_getref(m, key);
if (next) {
memcpy((*next)->value, value, vsize);
return 0;
}
/* Add new node */
node = map_newnode(key, value, vsize);
if (node == NULL) goto fail;
if (m->nnodes >= m->nbuckets) {
n = (m->nbuckets > 0) ? (m->nbuckets << 1) : 1;
err = map_resize(m, n);
if (err) goto fail;
}
map_addnode(m, node);
m->nnodes++;
return 0;
fail:
if (node) free(node);
return -1;
}
void map_remove_(map_base_t *m, const char *key) {
map_node_t *node;
map_node_t **next = map_getref(m, key);
if (next) {
node = *next;
*next = (*next)->next;
free(node);
m->nnodes--;
}
}
map_iter_t map_iter_(void) {
map_iter_t iter;
iter.bucketidx = -1;
iter.node = NULL;
return iter;
}
const char *map_next_(map_base_t *m, map_iter_t *iter) {
if (iter->node) {
iter->node = iter->node->next;
if (iter->node == NULL) goto nextBucket;
} else {
nextBucket:
do {
if (++iter->bucketidx >= m->nbuckets) {
return NULL;
}
iter->node = m->buckets[iter->bucketidx];
} while (iter->node == NULL);
}
return (char*) (iter->node + 1);
}
#endif

@ -0,0 +1,77 @@
/**
* Copyright (c) 2014 rxi
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MIT license. See LICENSE for details.
*/
#ifndef MAP_H
#define MAP_H
#include <string.h>
#define MAP_VERSION "0.1.0"
struct map_node_t;
typedef struct map_node_t map_node_t;
typedef struct {
map_node_t **buckets;
unsigned nbuckets, nnodes;
} map_base_t;
typedef struct {
unsigned bucketidx;
map_node_t *node;
} map_iter_t;
#define map_t(T)\
struct { map_base_t base; T *ref; T tmp; }
#define map_init(m)\
memset(m, 0, sizeof(*(m)))
#define map_deinit(m)\
map_deinit_(&(m)->base)
#define map_get(m, key)\
( (m)->ref = map_get_(&(m)->base, key) )
#define map_set(m, key, value)\
( (m)->tmp = (value),\
map_set_(&(m)->base, key, &(m)->tmp, sizeof((m)->tmp)) )
#define map_remove(m, key)\
map_remove_(&(m)->base, key)
#define map_iter(m)\
map_iter_()
#define map_next(m, iter)\
map_next_(&(m)->base, iter)
void map_deinit_(map_base_t *m);
void *map_get_(map_base_t *m, const char *key);
int map_set_(map_base_t *m, const char *key, void *value, int vsize);
void map_remove_(map_base_t *m, const char *key);
map_iter_t map_iter_(void);
const char *map_next_(map_base_t *m, map_iter_t *iter);
typedef map_t(void*) map_void_t;
typedef map_t(char*) map_str_t;
typedef map_t(int) map_int_t;
typedef map_t(char) map_char_t;
typedef map_t(float) map_float_t;
typedef map_t(double) map_double_t;
#endif

@ -0,0 +1,87 @@
#ifndef LINKED_LIST_C
#define LINKED_LIST_C
#include "linked_list.h"
/*
Author: xerox
Update: 1/20/2020
free's linked list.
*/
static void free_linked_list(node_info *p_list)
{
if (!p_list)
return;
node_info* temp;
while (p_list->next)
{
temp = p_list;
p_list = p_list->next;
free(temp);
}
}
/*
Author: xerox
Update: 1/20/2020
updates linked list.
*/
static node_info *copy_linked_list(node_info *p_list)
{
node_info* new_list = malloc(sizeof(node_info));
if (!new_list || !p_list)
return NULL;
new_list->next = NULL;
node_info *copy_list = new_list;
//TODO update with doubly linked list
while(p_list->next)
{
p_list = p_list->next;
copy_list->next = p_list;
}
return new_list;
}
/*
Author: xerox
Update: 1/20/2020
append to linked list.
*/
static void linked_list_append(node_info* p_head, node_info* new_node)
{
if (!p_head || !new_node)
return;
node_info* p_head_temp = p_head;
while (p_head->next)
p_head_temp = p_head_temp->next;
p_head->next = NULL; //sanity check
p_head_temp->next = p_head;
}
/*
Author: xerox
Update: 1/20/2020
remove link from linked list.
*/
static bool linked_list_remove(node_info* p_head, node_info* delete_node)
{
if (!p_head || !delete_node)
return false;
node_info* p_head_temp = p_head;
while (p_head_temp->next)
{
if (p_head_temp->next == delete_node)
{
p_head_temp->next = delete_node->next;
free(delete_node);
return true;
}
}
return false;
}
#endif

@ -0,0 +1,9 @@
#ifndef LINKED_LIST_H
#define LINKED_LIST_H
#include "../types.h"
void free_linked_list(node_info *p_list);
node_info *copy_linked_list(node_info *p_list);
void linked_list_append(node_info* p_head, node_info* new_node);
bool linked_list_remove(node_info* p_head, node_info* delete_node);
#endif

@ -0,0 +1,20 @@
#include "logic.h"
/*
Author: xerox
Date: 1/19/2020
creates logic given type, statement list to execute, and variable name for condition.
*/
static logic* create_logic(logic_type type, node_info* stmt_list, char* var_name)
{
logic* new_logic = malloc(sizeof(logic));
if (!new_logic || !stmt_list || !var_name)
return NULL;
memset(new_logic, NULL, sizeof(*new_logic));
new_logic->type = type;
new_logic->condition_var = var_name;
new_logic->stmt_list = stmt_list;
return new_logic;
}

@ -0,0 +1,5 @@
#ifndef LOGIC_H
#define LOGIC_H
#include "../types.h"
logic* create_logic(logic_type type, node_info* stmt_list, char* var_name);
#endif

@ -0,0 +1,257 @@
#ifndef PARSER_C
#define PARSER_C
#include "parser.h"
/*
Author: xerox
Updated: 1/19/2020
create variable given name, value, and type.
*/
static node_info* create_variable_const(char* p_name, void* value, variable_type var_type)
{
node_info* new_node = malloc(sizeof(*new_node));
if (!new_node)
return NULL;
memset(new_node, NULL, sizeof(*new_node));
variable* new_var = make_variable(p_name, value, var_type);
if (!new_var)
return NULL;
new_node->assignment = (assignment_operation*)malloc(sizeof(assignment_operation));
if (!new_node->assignment)
return NULL;
memset(new_node->assignment, NULL, sizeof(*new_node->assignment));
new_node->operation = ASSIGNMENT_OPERATION;
new_node->operation_type.assignment = ASSIGN_FROM_CONST;
new_node->assignment->var = new_var;
return new_node;
}
/*
Author: xerox
Updated: 1/20/2020
Move value from one variable to another.
*/
static node_info* move_value(char* to, char* from)
{
node_info* new_node = (node_info *)malloc(sizeof(node_info));
if (!from || !new_node || !to)
return NULL;
memset(new_node, NULL, sizeof(*new_node));
new_node->assignment = (assignment_operation*)malloc(sizeof(*new_node->assignment));
if (!new_node->assignment)
return NULL;
memset(new_node->assignment, NULL, sizeof(*new_node->assignment));
new_node->operation = ASSIGNMENT_OPERATION;
new_node->operation_type.assignment = ASSIGN_FROM_VAR;
new_node->assignment->from = from;
new_node->assignment->to = to;
return new_node;
}
/*
Author: xerox
Updated: 1/19/2020
create logic node (logical expression)
*/
static node_info* create_logic_node(logic* logic_expr)
{
node_info* new_node = malloc(sizeof(node_info));
if (!new_node || !logic_expr)
return NULL;
memset(new_node, NULL, sizeof(*new_node));
new_node->operation = LOGIC_OPERATION;
new_node->logical_expr = logic_expr;
return new_node;
}
/*
Author: xerox
Updated: 1/20/2020
Executes a statment.
@param nodeInfo statement to be executed
@return void.
*/
static void exec_stmt(node_info *exec_node)
{
if (!exec_node)
return;
switch (exec_node->operation)
{
case ASSIGNMENT_OPERATION:
switch (exec_node->operation_type.assignment)
{
case ASSIGN_FROM_CONST:
add_var(exec_node->assignment->var->name, exec_node->assignment->var->value, _var_map);
break;
case ASSIGN_FROM_VAR:
add_var(exec_node->assignment->to,
get_value(exec_node->assignment->from, _var_map), _var_map);
break;
default:
;
#if DEON_DEBUGGING
printf("[error] unkown assignment operation: 0x%x", exec_node->operation_type.assignment);
#endif
}
break;
case LOGIC_OPERATION:
{
switch (exec_node->logical_expr->type)
{
case IF_LOGIC:
{
variable_values* p_var_values = get_value(exec_node->logical_expr->condition_var, _var_map);
if (!p_var_values)
return;
if (*(unsigned char*)p_var_values->data_ptr)
exec_stmt(exec_node->logical_expr->stmt_list);
break;
}
case WHILE_LOGIC:
{
variable_values* p_var_values = get_value(exec_node->logical_expr->condition_var, _var_map);
if (!p_var_values)
return;
while (*(unsigned char*)p_var_values->data_ptr)
{
exec_stmt(exec_node->logical_expr->stmt_list);
p_var_values = get_value(exec_node->logical_expr->condition_var, _var_map);
}
break;
}
default:
;
#if DEON_DEBUGGING
printf("[error] unknown logic operation\n");
#endif
}
}
// execute statement list.
case EXEC_STMT_LIST_OPERATION:
{
if(exec_node->statement_list)
exec_node = exec_node->statement_list;
while (exec_node->next)
{
exec_node = exec_node->next;
exec_stmt(exec_node);
}
break;
}
// print statement
case PRINT_OPERATION:
{
switch (exec_node->operation_type.print)
{
case PRINT_CONSTANT:
{
switch (exec_node->print_expr->type)
{
case VAR_STRING:
printf("%s\n", (char*)exec_node->print_expr->value);
break;
case VAR_INT:
printf("%d\n", *(int*)exec_node->print_expr->value);
break;
case VAR_BYTE:
printf("%c\n", *(char*)exec_node->print_expr->value);
break;
case VAR_DOUBLE:
printf("%f\n", *(double*)exec_node->print_expr->value);
break;
case VAR_VOID: //TODO add void variable type
break;
default:
;
#if DEON_DEBUGGING
printf("[error] unable to print variable of type: 0x%x\n", exec_node->print_expr->type);
#endif
}
break;
}
case PRINT_VARIABLE:
{
variable_values* p_var = get_value(exec_node->var->name, _var_map);
switch (p_var->type)
{
case VAR_STRING:
printf("%s\n", (char*)p_var->data_ptr);
break;
case VAR_INT:
printf("%d\n", *(int*)p_var->data_ptr);
break;
case VAR_BYTE:
printf("%c\n", *(char*)p_var->data_ptr);
break;
case VAR_DOUBLE:
printf("%f\n", *(double*)p_var->data_ptr);
break;
case VAR_VOID: //TODO add void variable type
break;
default:
;
#if DEON_DEBUGGING
printf("[error] unable to print variable of type: 0x%x\n", p_var->type);
#endif
}
break;
}
default:
;
#if DEON_DEBUGGING
printf("[error] unknown print type: 0x%x\n", exec_node->operation_type.print);
#endif
}
break;
}
case FUNCTION_OPERATION:
{
switch (exec_node->operation_type.func)
{
case FUNCTION_CALL:
{
node_info* _stmts = *map_get(&*((map_void_t*)_function_list), exec_node->name);
_stmts = _stmts->statement_list;
while (_stmts->statement_list)
{
_stmts = _stmts->statement_list;
exec_stmt(_stmts);
}
break;
}
case FUNCTION:
{
if (!_function_list)
{
_function_list = malloc(sizeof(map_void_t));
map_init(_function_list);
map_set(_function_list, exec_node->name, exec_node->function_body);
}
else //else we dont malloc, we just put the function inside of the hashmap.
map_set(_function_list, exec_node->name, exec_node->function_body);
break;
}
default:
;
#if DEON_DEBUGGING
printf("[error] unknown function operation: 0x%x\n", exec_node->operation_type.func);
#endif
}
break;
}
default:
;
#if DEON_DEBUGGING
printf("[error] unknown operation: 0x%x\n", exec_node->operation);
#endif
}
}
#endif

@ -0,0 +1,9 @@
#ifndef PARSER_H
#define PARSER_H
#include "../types.h"
#include "../vars/vars.h"
node_info* create_variable_const(char* p_name, void* value, variable_type var_type);
node_info* move_value(char* to, char* from);
node_info* create_logic_node(logic* logic_expr);
void exec_stmt(node_info *exec_node);
#endif

@ -0,0 +1,54 @@
#ifndef PRINT_C
#define PRINT_C
#include "print.h"
/*
Author: xerox
Updated: 1/20/2020
creates a print statement given variable type and value.
*/
static node_info *create_print_statement(variable_type operation, void* value)
{
node_info* new_print_stmt = (node_info*)malloc(sizeof(node_info));
print* new_print = malloc(sizeof(print));
if (!new_print_stmt || !new_print)
return NULL;
memset(new_print_stmt, NULL, sizeof(*new_print_stmt));
memset(new_print, NULL, sizeof(*new_print));
new_print_stmt->operation = PRINT_OPERATION;
new_print_stmt->operation_type.print = PRINT_CONSTANT;
new_print->type = operation;
new_print->value = value;
new_print_stmt->print_expr = new_print;
new_print_stmt->next = NULL;
return new_print_stmt;
}
/*
Author: xerox
Updated: 1/19/2020
create print variable from variable name.
*/
static node_info* create_print_variable(char* var_name)
{
node_info* new_print_stmt = (node_info*)malloc(sizeof(node_info));
if (!new_print_stmt || !var_name)
return NULL;
memset(new_print_stmt, NULL, sizeof(*new_print_stmt));
new_print_stmt->var = malloc(sizeof(variable));
if (!new_print_stmt->var)
return NULL;
memset(new_print_stmt->var, NULL, sizeof(*new_print_stmt->var));
new_print_stmt->operation = PRINT_OPERATION;
new_print_stmt->operation_type.print = PRINT_VARIABLE;
new_print_stmt->var->name = var_name;
new_print_stmt->next = NULL;
return new_print_stmt;
}
#endif

@ -0,0 +1,6 @@
#ifndef PRINT_H
#define PRINT_H
#include "../types.h"
node_info* create_print_statement(variable_type operation, void* value);
node_info* create_print_variable(char* var_name);
#endif

@ -0,0 +1,128 @@
#ifndef INCLUDE_H
#define INCLUDE_H
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include "hashmap/map.h"
#define DEON_DEBUGGING 0
bool _DEON_DEBUG;
//--- different variable values
typedef enum _variable_type
{
VAR_INT,
VAR_SHORT,
VAR_BYTE,
VAR_DOUBLE,
VAR_STRING,
VAR_VOID
} variable_type;
//--- different function operations
typedef enum _function_type
{
FUNCTION,
FUNCTION_CALL,
} function_type;
//--- different print operations
typedef enum _print_type
{
PRINT_VARIABLE,
PRINT_CONSTANT
} print_type;
//--- different logic types
typedef enum _logic_type
{
IF_LOGIC,
WHILE_LOGIC
} logic_type;
typedef enum _assignment_type
{
ASSIGN_FROM_VAR,
ASSIGN_FROM_CONST
} assignment_type;
//--- all operations in the language
typedef enum _operation
{
ASSIGNMENT_OPERATION,
LOGIC_OPERATION,
EXEC_STMT_LIST_OPERATION,
PRINT_OPERATION,
FUNCTION_OPERATION,
};
//--- variable value details
typedef struct _variable_values
{
variable_type type;
void* data_ptr;
} variable_values;
//--- variable details
typedef struct _variable
{
char *name;
variable_values *value;
struct variable *next;
} variable;
//--- print data
typedef struct _print
{
enum _variable_type type;
void* value;
} print;
//--- assignment data
typedef struct _assignment_operation
{
char* from;
char* to;
variable* var;
}assignment_operation;
//--- logic operation data
typedef struct _logic
{
logic_type type;
char* condition_var;
struct node_info* stmt_list;
} logic;
//--- struct that brings it all together
typedef struct node_info
{
//--- node operation.
enum _operation operation;
//--- sub operations.
union _operation_type
{
logic_type logic;
function_type func;
print_type print;
assignment_type assignment;
} operation_type;
char *name;
print* print_expr;
logic* logical_expr;
assignment_operation* assignment;
variable* var;
struct node_info *next;
struct node_info *function_body;
struct node_info *statement_list;
struct node_info *new_scope;
struct map_void_t *var_map;
} node_info;
//--- globals
map_void_t* _var_map;
node_info* _temp_statement_head;
map_void_t* _function_list;
#endif

@ -0,0 +1,104 @@
#ifndef VARS_C
#define VARS_C
#include "vars.h"
/*
Author: xerox
Date: 1/20/2020
add var to hashmap of variables.
*/
static void add_var(char *p_name, variable_values *p_values, map_void_t* p_var_map)
{
if (!p_name || !p_values)
return;
map_set(p_var_map, p_name, p_values);
}
/*
Author: xerox
Date: 1/20/2020
get value given name and hashmap.
*/
static variable_values* get_value(char *p_name, map_void_t* p_var_map)
{
if (!p_name)
return NULL;
return *map_get(&*((map_void_t* ) p_var_map), p_name);
}
/*
Author: xerox
Date: 1/20/2020
makes a variable struct and define it.
*/
static variable* make_variable(char *p_name, void* value, variable_type var_type)
{
variable *new_var = malloc(sizeof(variable));
variable_values *new_value = malloc(sizeof(variable_values));
if (!new_var || !new_value || !p_name || !value)
return NULL;
memset(new_var, NULL, sizeof(*new_var));
memset(new_value, NULL, sizeof(*new_value));
new_value->type = var_type;
new_value->data_ptr = value;
new_var->name = p_name;
new_var->value = new_value;
return new_var;
}
/*
Author: xerox
Date: 1/20/2020
allocate memory for values that are 8 bytes or less.
*/
static void* alloc_value(void* value, variable_type var_type)
{
switch (var_type)
{
case VAR_INT:
{
int* p_int = (int*)malloc(sizeof(int));
if (!p_int)
return NULL;
memset(p_int, NULL, sizeof(*p_int));
*p_int = *(int*)value;
return p_int;
}
case VAR_SHORT:
{
short* p_short = (short*)malloc(sizeof(short));
if (!p_short)
return NULL;
memset(p_short, NULL, sizeof(*p_short));
*p_short = *(short*)value;
return p_short;
}
case VAR_BYTE:
{
char* p_char = malloc(sizeof(char));
if (!p_char)
return NULL;
memset(p_char, NULL, sizeof(*p_char));
*p_char = *(char*)value;
return p_char;
}
case VAR_DOUBLE:
{
double* p_double = malloc(sizeof(double));
if (!p_double)
return NULL;
memset(p_double, NULL, sizeof(*p_double));
*p_double = *(double*)value;
return p_double;
}
default:
return NULL;
}
}
#endif

@ -0,0 +1,8 @@
#ifndef VARS_H
#define VARS_H
#include "../types.h"
void add_var(char* name, variable_values* values, map_void_t* p_var_map);
variable* make_variable(char* p_name, void* value, variable_type var_type);
variable_values* get_value(char* p_name, map_void_t* p_var_map);
void* alloc_value(void* value, variable_type var_type);
#endif
Loading…
Cancel
Save