parent
527a4143b6
commit
92f790f084
@ -1,80 +0,0 @@
|
||||
%{
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "y.tab.h"
|
||||
|
||||
void yyerror(char *);
|
||||
|
||||
extern YYSTYPE yylval;
|
||||
extern FILE *yyin;
|
||||
int yylineno;
|
||||
int _DEBUG;
|
||||
|
||||
%}
|
||||
%%
|
||||
[//]* { ; }
|
||||
-?[0-9]+ { yylval.num = atoi(yytext); return INTEGER; }
|
||||
\'[ -~]\' { yylval.character = yytext[1]; return CHAR; }
|
||||
[-()<>=+*/:;,%{}\[\]] { return *yytext; }
|
||||
"if" { return IF; }
|
||||
"else" { return ELSE; }
|
||||
"printf" { return PRINTF; }
|
||||
"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 = strdup(yytext); return STRING; }
|
||||
[a-zA-Z0-9_]+ { yylval.str = strdup(yytext); return VARNAME; }
|
||||
-?[0-9]*\.[0-9]+ { yylval.Double = 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[])
|
||||
{
|
||||
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)
|
||||
{
|
||||
_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;
|
||||
}
|
@ -1,130 +0,0 @@
|
||||
%{
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "parser/parser.c"
|
||||
#include "functions/functions.c"
|
||||
#include "logic/logic.c"
|
||||
#include "print/print.c"
|
||||
#include "includes/include.h"
|
||||
|
||||
int yylex(void);
|
||||
void yyerror(char *);
|
||||
|
||||
extern int yylineno;
|
||||
extern int _DEBUG;
|
||||
|
||||
//hashmaps/link list heads
|
||||
map_void_t *_var_map = NULL;
|
||||
node_info *_temp_statement_head = NULL;
|
||||
//struct variable *_var_head = NULL;
|
||||
map_void_t *_function_list = NULL;
|
||||
|
||||
%}
|
||||
|
||||
/* 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;
|
||||
int num;
|
||||
char character;
|
||||
double Double;
|
||||
struct node_info *nPtr;
|
||||
|
||||
}
|
||||
|
||||
|
||||
%token INCREASE DECREASE PRINTF IF END KEYWORD_S KEYWORD_I KEYWORD_C QUOTE ELSE WHILE DEF CALL
|
||||
%token <num> INTEGER
|
||||
%token <str> STRING VARNAME
|
||||
%token <character> CHAR
|
||||
%token <Double> DOUBLEVAR
|
||||
%type <num> expr
|
||||
%type <nPtr> statement print VARIABLE FUNC statement_list
|
||||
|
||||
%%
|
||||
|
||||
program:
|
||||
|
||||
main '\n'
|
||||
|
|
||||
;
|
||||
|
||||
main:
|
||||
|
||||
main FUNC ';' { if (_DEBUG == 1 ) { printf(">>> "); ex($2); } else { ex($2); } }
|
||||
| FUNC ';' { if (_DEBUG == 1 ) { printf(">>> "); ex($1); } else { ex($1); } }
|
||||
| statement ';' { if (_DEBUG == 1 ) { printf(">>> "); ex($1); } else { ex($1); } }
|
||||
;
|
||||
|
||||
statement:
|
||||
|
||||
VARIABLE { $$ = $1; } //this is a real var dec.
|
||||
| FUNC { $$ = $1; }
|
||||
| IF '[' expr ']' ':' '{' statement_list '}' { $$ = create_logic(1, $3, $7, NULL); } //examples of logic in this language
|
||||
| WHILE '[' expr ']' ':' '{' statement_list '}' { $$ = create_logic(2, $3, $7, NULL); }
|
||||
| PRINTF'['print']' { $$ = $3; }
|
||||
| '{' statement_list '}' { $$ = $2; }
|
||||
;
|
||||
|
||||
statement_list:
|
||||
|
||||
statement ';' { $$ = create_compound_statement($1, _temp_statement_head); }
|
||||
| statement_list statement ';' { $$ = add_to_compound_statement($2, $1); }
|
||||
;
|
||||
|
||||
FUNC:
|
||||
|
||||
DEF VARNAME ':' '{' statement_list '}' { $$ = create_function($2, $5); } // defining functions
|
||||
| CALL VARNAME { $$ = create_function_call($2); } // calling functions
|
||||
;
|
||||
|
||||
VARIABLE:
|
||||
|
||||
VARNAME '=' STRING { $$ = create_var_assignment_string($1, $3);}
|
||||
| VARNAME '=' expr { $$ = create_var_assignment_int($1, $3);}
|
||||
| VARNAME '=' CHAR { $$ = create_var_assignment_char($1, $3);}
|
||||
| VARNAME '=' DOUBLEVAR { $$ = create_var_assignment_double($1, $3);}
|
||||
| VARNAME '=' '{' statement_list '}' { $$ = create_function($1, $4); } // you can also define functions like this
|
||||
;
|
||||
|
||||
|
||||
expr:
|
||||
INTEGER { $$ = $1; }
|
||||
| '{' KEYWORD_I '}' VARNAME { $$ = get_value($4, _var_map)->_int; }
|
||||
| expr '+' expr { $$ = $1 + $3; } /* addition */
|
||||
| expr '-' expr { $$ = $1 - $3; } /* subtration */
|
||||
| expr '*' expr { $$ = $1 * $3; } /* multiplication */
|
||||
| expr '/' expr { $$ = $1 / $3; } /* division */
|
||||
| expr '%' expr { $$ = $1 % $3; }
|
||||
| expr '>' expr { if ($1 > $3) { $$ = 1; } else { $$ = 0;}}
|
||||
| expr '<' expr { if ($1 < $3) { $$ = 1; } else { $$ = 0;}}
|
||||
| '(' expr ')' { $$ = $2; }
|
||||
;
|
||||
|
||||
//TODO update this.
|
||||
print:
|
||||
|
||||
VARNAME { $$ = create_print_var_node($1); }
|
||||
| expr { $$ = create_print_statement(1, $1, NULL); }
|
||||
| STRING { $$ = create_print_statement(2, 0, $1); }
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
void yyerror(char *s) {
|
||||
fprintf(stderr, "Error on line %d, %s\n", yylineno, s);
|
||||
}
|
||||
|
@ -1,20 +0,0 @@
|
||||
// another function
|
||||
def AnotherFunction : {
|
||||
printf["Hello from another function!"];
|
||||
};
|
||||
|
||||
|
||||
// every program needs a main :)
|
||||
def Main : {
|
||||
// define variables
|
||||
a = 10;
|
||||
b = 20;
|
||||
|
||||
// print statements
|
||||
printf["a + b: "];
|
||||
printf[{ int } a + b];
|
||||
|
||||
// calling functions
|
||||
call AnotherFunction;
|
||||
};
|
||||
call Main;
|
@ -1,72 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "functions.h"
|
||||
#include "../linked_list/linked_list.h"
|
||||
#include "../linked_list/linked_list.c"
|
||||
|
||||
|
||||
/**
|
||||
* Creates a function.
|
||||
*
|
||||
* @param char * to the name of the function
|
||||
* @param nodeInfo * to statement list
|
||||
* @return nodeInfo * to head
|
||||
*/
|
||||
node_info *create_function(char *p_name, node_info *p_stmts)
|
||||
{
|
||||
node_info *new_node = malloc(sizeof(node_info));
|
||||
new_node->opperation = 7;
|
||||
new_node->type = FUNCTION;
|
||||
new_node->name = p_name;
|
||||
new_node->_function_body = malloc(sizeof(node_info));
|
||||
new_node->_function_body->next = copy_linked_list(p_stmts);
|
||||
_free_linked_list(p_stmts);
|
||||
return new_node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a function
|
||||
*
|
||||
* @param name of the function
|
||||
* @return a node_info pointer to the head of the function
|
||||
*/
|
||||
node_info *create_function_call(char *p_name)
|
||||
{
|
||||
node_info *new_node = malloc(sizeof(node_info));
|
||||
new_node->opperation = 7;
|
||||
new_node->type = FUNCTION_CALL;
|
||||
new_node->name = p_name;
|
||||
new_node->next = NULL;
|
||||
return new_node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a linked list inside of a linked list
|
||||
*
|
||||
* @param new_statement_list to be appended to list
|
||||
* @param statement_head of linked list to append to
|
||||
*/
|
||||
node_info *create_compound_statement(node_info *new_statement_list, node_info *statement_head)
|
||||
{
|
||||
if(!statement_head)
|
||||
{
|
||||
statement_head = malloc(sizeof(node_info));
|
||||
node_info *newNode = malloc(sizeof(node_info));
|
||||
statement_head->opperation = 5;
|
||||
statement_head->next = new_statement_list;
|
||||
statement_head->next->next = NULL;
|
||||
statement_head->statement_list = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
node_info *p = statement_head;
|
||||
//TODO update with doubly linked list
|
||||
while(p->statement_list != NULL)
|
||||
p = p->statement_list;
|
||||
|
||||
p->next = malloc(sizeof(node_info));
|
||||
p->next = new_statement_list;
|
||||
p->next->next = NULL;
|
||||
}
|
||||
return statement_head;
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
#ifndef FUNCTIONS
|
||||
#define FUNCTIONS
|
||||
#include "../includes/include.h"
|
||||
|
||||
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);
|
||||
#endif
|
@ -1,186 +0,0 @@
|
||||
#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);
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
/**
|
||||
* 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
|
@ -1,84 +0,0 @@
|
||||
#ifndef INCLUDE_H
|
||||
#define INCLUDE_H
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "../hashmap/map.h"
|
||||
|
||||
/**
|
||||
* VariableType is a enum of varible types that will be inside of my language.
|
||||
*/
|
||||
typedef enum variable_type
|
||||
{
|
||||
VAR_STRING,
|
||||
VAR_INT,
|
||||
VAR_CHAR,
|
||||
VAR_DOUBLE,
|
||||
VAR_VOID
|
||||
} variable_type;
|
||||
|
||||
/**
|
||||
* VariableValues is a struct that holds all possible variable values
|
||||
*/
|
||||
typedef struct variable_values
|
||||
{
|
||||
variable_type type;
|
||||
char _char;
|
||||
char *_string;
|
||||
int _int;
|
||||
double _double;
|
||||
void* _void_pointer; //TODO create a concept of "void"
|
||||
} variable_values;
|
||||
|
||||
/**
|
||||
* Variables is a struct that has all the information needed for a variables
|
||||
*/
|
||||
typedef struct variable
|
||||
{
|
||||
char *name;
|
||||
variable_values *value;
|
||||
struct variable *next;
|
||||
} variable;
|
||||
|
||||
typedef struct print
|
||||
{
|
||||
int opperation;
|
||||
double value;
|
||||
char *string;
|
||||
} print;
|
||||
|
||||
typedef struct logic
|
||||
{
|
||||
int opperation;
|
||||
int expr;
|
||||
struct node_info *if_true;
|
||||
struct node_info *else_false;
|
||||
struct node_info *while_true;
|
||||
} logic;
|
||||
|
||||
|
||||
typedef struct node_info
|
||||
{
|
||||
int opperation;
|
||||
enum type{
|
||||
|
||||
ASSIGNMENT,
|
||||
EXPRESSION,
|
||||
STATEMENT,
|
||||
LOGIC,
|
||||
FUNCTION,
|
||||
FUNCTION_CALL
|
||||
|
||||
}type;
|
||||
char *name;
|
||||
variable *var;
|
||||
print printExpression;
|
||||
logic logicalExpression;
|
||||
struct node_info *next;
|
||||
struct node_info *_function_body;
|
||||
struct node_info *statement_list;
|
||||
struct node_info *local_list;
|
||||
struct map_void_t *_var_list;
|
||||
} node_info;
|
||||
#endif
|
@ -1,71 +0,0 @@
|
||||
#include "linked_list.h"
|
||||
|
||||
/**
|
||||
* free's a linked list
|
||||
* @param head of linked list to be freed
|
||||
* @return void
|
||||
*/
|
||||
void _free_linked_list(node_info *p_list)
|
||||
{
|
||||
node_info *temp;
|
||||
while(p_list->next)
|
||||
{
|
||||
temp = p_list;
|
||||
p_list = p_list->next;
|
||||
free(temp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a copy of list
|
||||
* @param nodeInfo list to be copied
|
||||
* @return copied list
|
||||
*/
|
||||
node_info *copy_linked_list(node_info *p_list)
|
||||
{
|
||||
node_info *new_list = malloc(sizeof(node_info));
|
||||
new_list->next = NULL;
|
||||
node_info *copy_list = new_list;
|
||||
while(p_list->next)
|
||||
{
|
||||
p_list = p_list->next;
|
||||
copy_list->next = p_list;
|
||||
copy_list = copy_list->next;
|
||||
}
|
||||
return new_list;
|
||||
}
|
||||
|
||||
/*
|
||||
@return void
|
||||
@param node_info* (head of linked list)
|
||||
@param node_info* (node to add)
|
||||
|
||||
Adds link to linked list.
|
||||
*/
|
||||
void linked_list_add(node_info* p_head, node_info* new_node)
|
||||
{
|
||||
node_info* p_head_temp = p_head;
|
||||
while (p_head->next)
|
||||
p_head_temp = p_head_temp->next;
|
||||
p_head_temp->next = p_head;
|
||||
}
|
||||
|
||||
/*
|
||||
@return bool (removed or not)
|
||||
@param node_info* (head of linked list)
|
||||
@param node_info* (node to delete from linked list)
|
||||
*/
|
||||
bool linked_list_remove(node_info* p_head, node_info* delete_node)
|
||||
{
|
||||
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;
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
#ifndef LINKED_LIST_H
|
||||
#define LINKED_LIST_H
|
||||
#include "../includes/include.h"
|
||||
|
||||
void _free_linked_list(node_info *p_list);
|
||||
node_info *copy_linked_list(node_info *p_list);
|
||||
void linked_list_add(node_info* p_head, node_info* new_node);
|
||||
bool linked_list_remove(node_info* p_head, node_info* delete_node);
|
||||
#endif
|
@ -1,40 +0,0 @@
|
||||
#include "../includes/include.h"
|
||||
|
||||
/*
|
||||
* WARNING! do not use this function, it is old and outdated, and is missing alot of new features!
|
||||
*/
|
||||
node_info *create_logic(int opperation, int expr, node_info *statement_list, node_info *else_false)
|
||||
{
|
||||
node_info *n = malloc(sizeof(node_info));
|
||||
switch (opperation)
|
||||
{
|
||||
case 1: //if statement
|
||||
n->opperation = 4;
|
||||
logic a;
|
||||
a.opperation = 1;
|
||||
a.expr = expr;
|
||||
while (statement_list->statement_list)
|
||||
statement_list = statement_list->statement_list;
|
||||
node_info *newNode = malloc(sizeof(node_info));
|
||||
newNode->opperation = 5;
|
||||
newNode->next = copy_linked_list(statement_list);
|
||||
_free_linked_list(statement_list);
|
||||
a.if_true = newNode;
|
||||
statement_list = NULL;
|
||||
n->logicalExpression = a;
|
||||
return n;
|
||||
|
||||
case 2: //while loop
|
||||
/*n->opperation = 4;
|
||||
logic b;
|
||||
b.opperation = 2;
|
||||
b.expr = expr;
|
||||
b.while_true = if_true;
|
||||
|
||||
n->logicalExpression = b;
|
||||
return n;*/
|
||||
break;
|
||||
default:
|
||||
printf("check your yacc file for logical statements\n");
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
#ifndef LOGIC_H
|
||||
#define LOGIC_H
|
||||
node_info *createLogic(int opperation, int expr, node_info *statement_list, node_info *else_false);
|
||||
#endif
|
@ -1,3 +0,0 @@
|
||||
lex deon.l
|
||||
yacc -d deon.y
|
||||
gcc hashmap/map.c lex.yy.c y.tab.c -o deon
|
@ -1,211 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "parser.h"
|
||||
#include "../vars/vars.c"
|
||||
|
||||
//hashmaps/link list heads
|
||||
extern map_void_t *_var_map;
|
||||
extern node_info *_temp_statement_head;
|
||||
//struct variable *_var_head = NULL;
|
||||
extern map_void_t *_function_list;
|
||||
|
||||
node_info* create_var_assignment_string(char *p_name, char *value)
|
||||
{
|
||||
node_info *new_node = malloc(sizeof(node_info));
|
||||
variable *new_var = make_variable_string(p_name, value);
|
||||
new_node->type = ASSIGNMENT;
|
||||
new_node->opperation = 1;
|
||||
new_node->var = new_var;
|
||||
return new_node;
|
||||
}
|
||||
|
||||
node_info* create_var_assignment_int(char *p_name, int value)
|
||||
{
|
||||
node_info *new_node = malloc(sizeof(node_info));
|
||||
variable *new_var = make_variable_int(p_name, value);
|
||||
new_node->type = ASSIGNMENT;
|
||||
new_node->opperation = 1;
|
||||
new_node->var = new_var;
|
||||
return new_node;
|
||||
}
|
||||
|
||||
node_info* create_var_assignment_char(char *p_name, char value)
|
||||
{
|
||||
node_info *new_node = malloc(sizeof(node_info));
|
||||
variable *new_var = make_variable_char(p_name, value);
|
||||
new_node->type = ASSIGNMENT;
|
||||
new_node->opperation = 1;
|
||||
new_node->var = new_var;
|
||||
return new_node;
|
||||
}
|
||||
|
||||
node_info* create_var_assignment_double(char *p_name, double value)
|
||||
{
|
||||
node_info *new_node = malloc(sizeof(node_info));
|
||||
variable *new_var = make_variable_double(p_name, value);
|
||||
//new node stuff
|
||||
new_node->type = ASSIGNMENT;
|
||||
new_node->opperation = 1;
|
||||
new_node->var = new_var;
|
||||
return new_node;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Adds statement to linked list.
|
||||
|
||||
@param nodeInfo link to be added.
|
||||
@return head of linked list.
|
||||
*/
|
||||
node_info* add_to_compound_statement(node_info *new_statement, node_info *statement_head)
|
||||
{
|
||||
if(!statement_head)
|
||||
{
|
||||
statement_head = malloc(sizeof(node_info));
|
||||
statement_head->opperation = 5;
|
||||
statement_head->next = new_statement;
|
||||
statement_head->next->next = NULL;
|
||||
statement_head->statement_list = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
node_info *p = statement_head; //make a temp of list head, so we can traverse it
|
||||
//TODO replace with double linked list end
|
||||
while (p->statement_list)
|
||||
p = p->statement_list;
|
||||
|
||||
//TODO replace with double linked list end
|
||||
while (p->next)
|
||||
p = p->next;
|
||||
|
||||
p->next = malloc(sizeof(node_info));
|
||||
p->next = new_statement;
|
||||
p->next->next = NULL;
|
||||
}
|
||||
return statement_head;
|
||||
}
|
||||
|
||||
/*
|
||||
Executes a statment.
|
||||
|
||||
@param nodeInfo statement to be executed
|
||||
@return void.
|
||||
*/
|
||||
|
||||
//TODO break this switch up into multiple functions
|
||||
//TODO return status code possibly.
|
||||
void ex(node_info *exec_node)
|
||||
{
|
||||
switch(exec_node->opperation)
|
||||
{
|
||||
case 1:
|
||||
add_var(exec_node->var->name, exec_node->var->value, _var_map);
|
||||
break;
|
||||
//TODO expression stuff
|
||||
case 2:
|
||||
break;
|
||||
//print
|
||||
case 3:
|
||||
switch(exec_node->printExpression.opperation) {
|
||||
|
||||
case 1:
|
||||
printf("%d\n", (int) exec_node->printExpression.value);
|
||||
break;
|
||||
case 2:
|
||||
printf("%s\n", exec_node->printExpression.string);
|
||||
break;
|
||||
case 3:
|
||||
printf("%s%lf\n", exec_node->printExpression.string, exec_node->printExpression.value);
|
||||
break;
|
||||
default:
|
||||
printf("{ERROR} CHECK YACC FILE FOR INCORRECT PRINT\n");
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
{
|
||||
switch(exec_node->logicalExpression.opperation) {
|
||||
case 1:
|
||||
if (exec_node->logicalExpression.expr == 1)
|
||||
ex(exec_node->logicalExpression.if_true);
|
||||
break;
|
||||
case 2:
|
||||
while (exec_node->logicalExpression.expr == 1)
|
||||
ex(exec_node->logicalExpression.while_true);
|
||||
break;
|
||||
default:
|
||||
printf("{ERROR} SOMETHING WRONG WITH LOGICAL EXPRESSION CHECK YACC\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
while(exec_node->next)
|
||||
{
|
||||
exec_node = exec_node->next;
|
||||
ex(exec_node);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
variable_values *value = get_value(exec_node->name, _var_map);
|
||||
switch(value->type)
|
||||
{
|
||||
case VAR_STRING:
|
||||
printf("%s\n", value->_string);
|
||||
break;
|
||||
case VAR_INT:
|
||||
printf("%d\n", value->_int);
|
||||
break;
|
||||
case VAR_CHAR:
|
||||
printf("%c\n", value->_char);
|
||||
break;
|
||||
case VAR_DOUBLE:
|
||||
printf("%f\n", value->_double);
|
||||
break;
|
||||
case VAR_VOID: //TODO add void variable type
|
||||
break;
|
||||
default:
|
||||
printf("{ERROR} NO SUCH VARIABLE TYPE CHECK YACC!\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
switch(exec_node->type)
|
||||
{
|
||||
case FUNCTION_CALL:
|
||||
{
|
||||
node_info *_stmts = *map_get(&*((map_void_t* ) _function_list), exec_node->name);
|
||||
while (_stmts->next != NULL)
|
||||
{
|
||||
_stmts = _stmts->next;
|
||||
ex(_stmts);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FUNCTION:
|
||||
{
|
||||
//if the list of functions already defined is null then we malloc space for it.
|
||||
if (!_function_list)
|
||||
{
|
||||
_function_list = malloc(sizeof(map_void_t));
|
||||
exec_node->_var_list = malloc(sizeof(node_info));
|
||||
exec_node->next = NULL;
|
||||
exec_node->local_list = NULL;
|
||||
map_init(&*((map_void_t *) _function_list));
|
||||
map_init(&*((map_void_t *) exec_node->_var_list));
|
||||
//put the function in the hashmap
|
||||
map_set(&*((map_void_t* ) _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(&*((map_void_t* ) _function_list), exec_node->name, &*exec_node->_function_body);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
;
|
||||
//TODO add error here and close
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
#ifndef PARSER_H
|
||||
#define PARSER_H
|
||||
#include "../includes/include.h"
|
||||
|
||||
node_info* create_var_assignment_string(char *p_name, char *value);
|
||||
node_info* create_var_assignment_int(char *p_name, int value);
|
||||
node_info* create_var_assignment_char(char *pName, char value);
|
||||
node_info* create_var_assignment_double(char *pName, double value);
|
||||
node_info* add_to_compound_statement(node_info *new_statement, node_info *statement_head);
|
||||
void ex(node_info *exec_node);
|
||||
#endif
|
@ -1,53 +0,0 @@
|
||||
#include "../includes/include.h"
|
||||
|
||||
/**
|
||||
* Creates a print node
|
||||
*
|
||||
* @param pVarName name of variable to print
|
||||
* @return node_info print statement
|
||||
*/
|
||||
node_info *create_print_var_node(char *p_var_name)
|
||||
{
|
||||
node_info *new_node = malloc(sizeof(node_info));
|
||||
new_node->opperation = 6;
|
||||
new_node->name = p_var_name;
|
||||
return new_node;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @params opperation value, see print struct for info
|
||||
* @params int value to be printed
|
||||
* @params string to be printed
|
||||
*
|
||||
*/
|
||||
|
||||
node_info *create_print_statement(int opperation, int value, char *string)
|
||||
{
|
||||
node_info *n = malloc(sizeof(node_info));
|
||||
print a;
|
||||
switch(opperation)
|
||||
{
|
||||
case 1:
|
||||
n->opperation = 3;
|
||||
a.value = value;
|
||||
a.opperation = 1;
|
||||
n->printExpression = a;
|
||||
return n;
|
||||
case 2:
|
||||
n->opperation = 3;
|
||||
a.string = string;
|
||||
a.opperation = 2;
|
||||
n->printExpression = a;
|
||||
return n;
|
||||
case 3:
|
||||
n->opperation = 3;
|
||||
a.string = string;
|
||||
a.opperation = 3;
|
||||
a.value = value;
|
||||
n->printExpression = a;
|
||||
return n;
|
||||
default:
|
||||
printf("{ERROR} PRINT STATEMENT ERROR IN YACC\n");
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
#ifndef PRINT_H
|
||||
#define PRINT_H
|
||||
node_info *create_print_var_node(char *pVarName);
|
||||
node_info *create_print_statement(int opperation, int value, char *string);
|
||||
#endif
|
@ -1,107 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "vars.h"
|
||||
|
||||
/**
|
||||
* Version: 0.2
|
||||
*
|
||||
* adds var to hashmap if its not already set
|
||||
* else it will update the var with provided values.
|
||||
* @return null
|
||||
* @param string for var name
|
||||
*
|
||||
*/
|
||||
void add_var(char *p_name, variable_values *p_values, map_void_t* p_var_map)
|
||||
{
|
||||
//if variable map is null
|
||||
if(!p_var_map)
|
||||
{
|
||||
p_var_map = malloc(sizeof(map_void_t));
|
||||
map_init(&*((map_void_t *) p_var_map));
|
||||
}
|
||||
map_set(&*((map_void_t* ) p_var_map), p_name, &*p_values);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns variables values from hashmap
|
||||
*
|
||||
* @see [variable_values]
|
||||
* @see [char *string]
|
||||
* @return [variable_values] containing variables data
|
||||
* @param [char *string] Variable name.
|
||||
*
|
||||
*/
|
||||
variable_values *get_value(char *p_name, map_void_t* p_var_map)
|
||||
{
|
||||
return *map_get(&*((map_void_t* ) p_var_map), p_name);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* This makes an integer varible and adds it to the linked list of
|
||||
* vars.
|
||||
* @return the head of the linked list which just points to all of the vars
|
||||
*
|
||||
*/
|
||||
variable* make_variable_int(char *p_name, int value)
|
||||
{
|
||||
variable *p = malloc(sizeof(variable));
|
||||
variable_values *int_value = malloc(sizeof(variable_values));
|
||||
int_value->type = VAR_INT;
|
||||
int_value->_int = value;
|
||||
p->name = p_name;
|
||||
p->value = int_value;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* makes a variable of type double.
|
||||
* @param name of the varible.
|
||||
* @param double data to be stored in the variable.
|
||||
*/
|
||||
variable* make_variable_double(char *p_name, double value)
|
||||
{
|
||||
variable *new_var = malloc(sizeof(variable));
|
||||
variable_values *double_value = malloc(sizeof(variable_values));
|
||||
double_value->type = VAR_DOUBLE;
|
||||
double_value->_double = value;
|
||||
new_var->name = p_name;
|
||||
new_var->value = double_value;
|
||||
return new_var;
|
||||
}
|
||||
|
||||
/**
|
||||
* makes a char variable.
|
||||
*
|
||||
* @param name of the variable.
|
||||
* @param char value to be stored.
|
||||
*/
|
||||
variable* make_variable_char(char *p_name, char value)
|
||||
{
|
||||
variable *p = malloc(sizeof(variable));
|
||||
variable_values *char_value = malloc(sizeof(variable_values));
|
||||
char_value->type = VAR_CHAR;
|
||||
char_value->_char = value;
|
||||
p->name = p_name;
|
||||
p->value = char_value;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* makes a variable of type string.
|
||||
*
|
||||
* @param name of the variable.
|
||||
* @param value to be stored.
|
||||
*/
|
||||
variable* make_variable_string(char *p_name, char *value)
|
||||
{
|
||||
variable *p = malloc(sizeof(variable));
|
||||
variable_values *string_value = malloc(sizeof(variable_values));
|
||||
string_value->type = VAR_STRING;
|
||||
string_value->_string = value;
|
||||
p->name = p_name;
|
||||
p->value = string_value;
|
||||
return p;
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
#ifndef VARS_H
|
||||
#define VARS_H
|
||||
#include "../includes/include.h"
|
||||
void add_var(char *name, variable_values *values, map_void_t* p_var_map);
|
||||
variable_values *get_value(char *p_name, map_void_t* p_var_map);
|
||||
variable* make_variable_int(char *p_name, int value);
|
||||
variable* make_variable_double(char *p_name, double value);
|
||||
variable* make_variable_char(char *p_name, char value);
|
||||
variable* make_variable_string(char *p_name, char *value);
|
||||
#endif
|
@ -1,116 +0,0 @@
|
||||
/* A Bison parser, made by GNU Bison 3.0.4. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
under terms of your choice, so long as that work isn't itself a
|
||||
parser generator using the skeleton or a modified version thereof
|
||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||
the parser skeleton itself, you may (at your option) remove this
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
#ifndef YY_YY_Y_TAB_H_INCLUDED
|
||||
# define YY_YY_Y_TAB_H_INCLUDED
|
||||
/* Debug traces. */
|
||||
#ifndef YYDEBUG
|
||||
# define YYDEBUG 0
|
||||
#endif
|
||||
#if YYDEBUG
|
||||
extern int yydebug;
|
||||
#endif
|
||||
|
||||
/* Token type. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
enum yytokentype
|
||||
{
|
||||
INCREASE = 258,
|
||||
DECREASE = 259,
|
||||
PRINTF = 260,
|
||||
IF = 261,
|
||||
END = 262,
|
||||
KEYWORD_S = 263,
|
||||
KEYWORD_I = 264,
|
||||
KEYWORD_C = 265,
|
||||
QUOTE = 266,
|
||||
ELSE = 267,
|
||||
WHILE = 268,
|
||||
DEF = 269,
|
||||
CALL = 270,
|
||||
INTEGER = 271,
|
||||
STRING = 272,
|
||||
VARNAME = 273,
|
||||
CHAR = 274,
|
||||
DOUBLEVAR = 275
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
#define INCREASE 258
|
||||
#define DECREASE 259
|
||||
#define PRINTF 260
|
||||
#define IF 261
|
||||
#define END 262
|
||||
#define KEYWORD_S 263
|
||||
#define KEYWORD_I 264
|
||||
#define KEYWORD_C 265
|
||||
#define QUOTE 266
|
||||
#define ELSE 267
|
||||
#define WHILE 268
|
||||
#define DEF 269
|
||||
#define CALL 270
|
||||
#define INTEGER 271
|
||||
#define STRING 272
|
||||
#define VARNAME 273
|
||||
#define CHAR 274
|
||||
#define DOUBLEVAR 275
|
||||
|
||||
/* Value type. */
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
|
||||
union YYSTYPE
|
||||
{
|
||||
#line 38 "deon.y" /* yacc.c:1909 */
|
||||
|
||||
|
||||
char *str;
|
||||
int num;
|
||||
char character;
|
||||
double Double;
|
||||
struct node_info *nPtr;
|
||||
|
||||
|
||||
#line 104 "y.tab.h" /* yacc.c:1909 */
|
||||
};
|
||||
|
||||
typedef union YYSTYPE YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
#endif
|
||||
|
||||
|
||||
extern YYSTYPE yylval;
|
||||
|
||||
int yyparse (void);
|
||||
|
||||
#endif /* !YY_YY_Y_TAB_H_INCLUDED */
|
Loading…
Reference in new issue