master
john doe 5 years ago
commit c2411d97e9

@ -0,0 +1,111 @@
# Deon programming language V0.9.1 update notes
My computer programming language made with LEX/YACC written in C. (interpreted)
* Moved nodeInfo declarations to its own folder/file
* Moved print declarations to its own folder/file
* Moved heads of linked lists/hashmaps to headerfiles
# Making a program.
Everything in this language is based around "Structs". These are not the regular structs that are in C.
To make a hello world program it would look like this:
```
def Main : {
printf[ "hello world" ];
};
call Main;
```
Requirements to making a program:
1.) a struct.
2.) a call statement.
# 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. For example, all positive numbers will be treated like an unsigned long double.
```
myint = 121231; // double (unsigned long)
mydouble = -123.122; // double (signed double)
mystring = "cool string"; // string
mychar = 'c'; // char
myfunction = { printf[ "hello world" ]; }; (statement list)
```
Variables are scoped to the struct that they are defined in. This is so everything is not global. An example of this would look:
```
def MyDog : {
age = -153000;
name = "i dont have a name";
printfMyName = {
printf[ name ];
};
};
def Main : {
someOtherAge = 2;
myRealDogsName = "cat"; // because variable naming is the hardest thing in computer science.
printfMyName = {
printf[ someOtherAge ];
};
call MyDog::printfMyName;
/*
When you do not use the scope resolution modifier then it will only check local functions.
The local function hashmap is stored in the head of your functions linked list.
/*
call printfMyName
};
call Main;
```
# Logic
Logic is first evaluated and if deemed valid then a list of statements will be executed.
```
if [ 10 > 9 ]: {
printf [ "10 is bigger than 9!" ];
newInt = 100;
};
if [ {int} newInt > 99 ]: {
printf [ "newInt is bigger than 99" ];
};
```
# 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.
```
def NewStruct : {
someFunction = {
printf[ "hello world" ];
};
};
call NewStruct;
```
# Coming soon
TCP networking, file handling, and finally loops!

BIN
deon

Binary file not shown.

@ -0,0 +1,85 @@
%{
#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");
}
} else {
printf("[ ERROR ] missing input file. Try --help?\n");
}
return 0;
}

121
deon.y

@ -0,0 +1,121 @@
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "parser/parser.c"
int yylex(void);
void yyerror(char *);
extern int yylineno;
extern int _DEBUG;
%}
/* 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 nodeInfo *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 '}' { $$ = createLogic(1, $3, $7, NULL); } //examples of logic in this language
| WHILE '[' expr ']' ':' '{' statement_list '}' { $$ = createLogic(2, $3, $7, NULL); }
| PRINTF'['print']' { $$ = $3; }
| '{' statement_list '}' { $$ = $2; }
;
statement_list:
statement ';' { $$ = createCompoundStatement($1); }
| statement_list statement ';' { $$ = addToCompoundStatement($2); }
;
FUNC:
DEF VARNAME ':' '{' statement_list '}' { $$ = createFunction($2, $5); } // defining functions
| CALL VARNAME { $$ = createFunctionCall($2); } // calling functions
;
VARIABLE:
VARNAME '=' STRING { $$ = createVarAssignmentString($1, $3);}
| VARNAME '=' expr { $$ = createVarAssignmentInt($1, $3);}
| VARNAME '=' CHAR { $$ = createVarAssignmentChar($1, $3);}
| VARNAME '=' DOUBLEVAR { $$ = createVarAssignmentDouble($1, $3);}
| VARNAME '=' '{' statement_list '}' { $$ = createFunction($1, $4); } // you can also define functions like this
;
expr:
INTEGER { $$ = $1; }
| '{' KEYWORD_I '}' VARNAME { $$ = getValue($4)->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; }
;
print:
VARNAME { $$ = createPrintVarNode($1); }
| expr { $$ = createPrintStatement(1, $1, NULL); }
| STRING { $$ = createPrintStatement(2, 0, $1); }
| ',' print { $$ = $2; }
;
%%
void yyerror(char *s) {
fprintf(stderr, "Error on line %d, %s\n", yylineno, s);
}

@ -0,0 +1,9 @@
i = 10;
def a :
if [ {int} i > 4 ] :
i = {int} i - 1;
call a;
printf [ {int} i ];

@ -0,0 +1,13 @@
if [ 10 > 9 ]:
printf [ "ten is bigger than 9" ];,
new_int = 10;
if [ {int} new_int > 9 ]:
printf [ "new_int is bigger than 9!" ];,
another_int = 100;
if [ {int} another_int > 1000 ]:
printf [ "this wont print!" ];

@ -0,0 +1,18 @@
def AnotherFunction: {
printf[ "another Function!" ];
};
def Main : {
if [ 10 > 4 ]: {
printf[ "hello world" ];
};
};
call Main;

@ -0,0 +1,11 @@
def Main : {
printf["hello world"];
a = 10;
printf[a];
};
call Main;

@ -0,0 +1,14 @@
myint = 10;
mystring = "anything you want????";
mychar = 'a';
another_char = '!';
printf [ mystring ];
printf [ {int} myint ];
printf [ another_char ];
myint = "my int is not a string!";
mychar = 109;
printf [ myint ];
printf [ {int} mychar ];

@ -0,0 +1,193 @@
/**
* 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.
*/
#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);
}

@ -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,6 @@
typedef struct link {
} link;

@ -0,0 +1,17 @@
typedef struct Logic {
struct enum logicType {
IF,
ELSE,
WHILE,
FOR
} logicType;
} Logic;
bool evalCondition()

@ -0,0 +1,5 @@
#include "logic.c"
typedef struct enum Logic Logic;
Logic *createLogic(LogicType type, LogicCondition *condition, nodeInfo *statementList);
bool condition(LogicCondition *condition);

@ -0,0 +1,9 @@
#include "logic.h"
#include <stdio.h>
int main() {
return 0;
}

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

Binary file not shown.

@ -0,0 +1,12 @@
#include <stdlib.h>
#include "socket.h"
int main() {
Socket news = create_lsocket(5001, 5);
printf("Created socket!\n");
sleep(10);
return 0;
}

@ -0,0 +1,134 @@
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <strings.h>
/**
*
* socket struct for building sockets...
* This will hold both listening sockets and connection sockets
* TCP AND UDP!
*
*/
typedef struct Socket {
int socketfd; //socket id
int client_socketfd; // this is the int you get when you call accept()
int port; // port information
struct sockaddr_in address; // sockaddr_in struct
struct Socket *next; // next in the linked list
} Socket;
//head of the linked list of sockets
struct Socket *_socket_head = NULL;
/**
* This is used by a thread to listen for incoming
* connections
*
*/
void doprocessing (int sock) {
int n;
char buffer[256];
bzero(buffer,256);
while(1) {
n = read(sock,buffer,255);
if (n < 0) {
perror("ERROR reading from socket");
exit(1);
}
printf("Here is the message: %s\n",buffer);
n = write(sock,"I got your message",18);
if (n < 0) {
perror("ERROR writing to socket");
exit(1);
}
}
}
/**
*
* This function creates a listening function...
* @params takes a an int for a port.
* @return An active listening socket for incoming connections
*
*/
Socket create_lsocket(int _port, int _connection_amount) {
Socket *newSocket = malloc(sizeof(Socket));
//sockaddr_in struct stuff (making a new sockaddr_in and giving it details)
struct sockaddr_in address; // make a struct of type sockaddr_in
int addr_size = sizeof(address); // size of addess in decimal form
// filling our struct with info
address.sin_family = AF_INET; //ipv4....
address.sin_addr.s_addr = INADDR_ANY; // any local address I.E :0.0.0.0
address.sin_port = htons(_port); // htons takes a decimal number and converts it to network
//this is a socket handler, like a file handler...
int socketfd = socket(AF_INET, SOCK_STREAM, 0);
// if the socks returns 0 then exit
if (socketfd == 0) {
printf("SOCKET FAILED!\n");
exit(1);
}
//lets bind that socket now
int bindRes = bind(socketfd, (struct sockaddr *)&address, sizeof(address));
if(bindRes < 0) {
printf("BIND FAILED! WITH CODE: %d\n", bindRes);
exit(1);
}
listen(socketfd, 5);
while(1) {
int newsockfd = accept(socketfd, (struct sockaddr *) &address, &addr_size);
if (newsockfd < 0) {
printf("ERROR LISTENING!\n");
exit(1);
}
int pid = fork();
if (pid == 0) {
printf("NEW CLIENT!\n");
doprocessing(newsockfd);
exit(0);
}
}
newSocket->socketfd = socketfd;
newSocket->port = _port;
newSocket->address = address;
newSocket->next = NULL;
// if the socket head is empty we are going to malloc the head and then start
// the linked list of sockets
if (_socket_head == NULL) {
_socket_head = malloc(sizeof(Socket));
_socket_head->next = newSocket;
}
}

Binary file not shown.

@ -0,0 +1,17 @@
socket = l_SOCKET("0.0.0.0", 90); //creates a server socket
client = C_SOCKET("127.0.0.1", 90); // creates a client
socket.template = {
"HEADER-DATA" : varToSaveData : call responce;,
"SOMEOTHER-HEADER" : varToSaveData : call responce;
}
client.plan = {
}

@ -0,0 +1,87 @@
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <strings.h>
void doprocessing (int sock) {
int n;
char buffer[256];
bzero(buffer,256);
while(1) {
n = read(sock,buffer,255);
if (n < 0) {
perror("ERROR reading from socket");
exit(1);
}
printf("Here is the message: %s\n",buffer);
n = write(sock,"I got your message",18);
if (n < 0) {
perror("ERROR writing to socket");
exit(1);
}
}
}
int main() {
int port = 5001;
struct sockaddr_in address;
int clilen = sizeof(address);
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(port);
int socketHandler = socket(AF_INET, SOCK_STREAM, 0);
if (socketHandler == 0) {
printf("SOCKET FAILED!\n");
return 1;
} else {
printf("SETUP SOCKET!\n");
}
int bindRes = bind(socketHandler, (struct sockaddr *)&address, sizeof(address));
if(bindRes < 0) {
printf("BIND FAILED! CODE: %d\n", bindRes);
} else {
printf("BINDED SOCKET!\n");
}
listen(socketHandler, 5);
while(1) {
int newsockfd = accept(socketHandler, (struct sockaddr *) &address, &clilen);
if (newsockfd < 0) {
printf("ERROR LISTENING!\n");
exit(1);
}
int pid = fork();
if (pid == 0) {
printf("NEW CLIENT!\n");
doprocessing(newsockfd);
exit(0);
}
}
return 0;
}

@ -0,0 +1,534 @@
#include <stdio.h>
#include "parser.h"
#include "../vars/vars.h"
#include "../hashmap/map.h"
//TODO put in header
void ex();
//TODO make a seperate file for this
typedef struct print {
int opperation;
double value;
char *string;
} print;
//TODO make a seperate file for this
typedef struct logic {
int opperation;
int expr;
struct nodeInfo *if_true;
struct nodeInfo *else_false;
struct nodeInfo *while_true;
} logic;
//TODO make a seperate file for this.
typedef struct nodeInfo {
int opperation;
enum type{
ASSIGNMENT,
EXPRESSION,
STATEMENT,
LOGIC,
FUNCTION,
FUNCTION_CALL
}type;
char *name;
Variable *var;
print printExpression;
logic logicalExpression;
struct nodeInfo *next;
struct nodeInfo *_function_body;
struct nodeInfo *statement_list;
struct nodeInfo *local_list;
struct map_void_t *local_var_list;
} nodeInfo;
//linked list heads. (move to a header file.)
//TODO put in header.
struct nodeInfo *statementHead = NULL;
struct Variable *head = NULL;
struct map_void_t *_function_list = NULL;
nodeInfo *createFunctionCall(char *_name) {
nodeInfo *newNode = malloc(sizeof(nodeInfo));
newNode->type = FUNCTION_CALL;
newNode->name = _name;
newNode->next = NULL;
return newNode;
}
/**
* free's a list's links.
* @param list of linked list to be free'ed
* @return void
*/
void freeLinkedList(nodeInfo *list) {
statementHead = NULL;
}
/**
* returns a copy of list
* @param nodeInfo list to be copied
* @return copied list
*/
nodeInfo *copyLinkedList(nodeInfo *list) {
nodeInfo *newList = malloc(sizeof(nodeInfo));
newList->next = NULL;
nodeInfo *copy_list = newList;
while(list->next != NULL) {
list = list->next;
copy_list->next = list;
copy_list = copy_list->next;
}
return newList;
}
nodeInfo *createFunction(char *_name, nodeInfo *_stmts) {
nodeInfo *newNode = malloc(sizeof(nodeInfo));
newNode->type = FUNCTION;
newNode->name = _name;
newNode->_function_body = malloc(sizeof(nodeInfo));
newNode->_function_body->next = copyLinkedList(_stmts);
freeLinkedList(_stmts);
return newNode;
}
nodeInfo* createVarAssignmentString(char *name, char *string) {
nodeInfo *newNode = malloc(sizeof(nodeInfo));
Variable *newVar = makeVariableString(name, string);
newNode->type = ASSIGNMENT;
newNode->opperation = 1;
newNode->var = newVar;
return newNode;
}
nodeInfo* createVarAssignmentInt(char *name, int number) {
nodeInfo *newNode = malloc(sizeof(nodeInfo));
Variable *newVar = makeVariableInt(name, number);
newNode->type = ASSIGNMENT;
newNode->opperation = 1;
newNode->var = newVar;
return newNode;
}
nodeInfo* createVarAssignmentChar(char *name, char Char) {
nodeInfo *newNode = malloc(sizeof(nodeInfo));
Variable *newVar = makeVariableChar(name, Char);
newNode->type = ASSIGNMENT;
newNode->opperation = 1;
newNode->var = newVar;
return newNode;
}
nodeInfo* createVarAssignmentDouble(char *name, double Double) {
nodeInfo *newNode = malloc(sizeof(nodeInfo));
Variable *newVar = makeVariableDouble(name, Double);
//new node stuff
newNode->type = ASSIGNMENT;
newNode->opperation = 1;
newNode->var = newVar;
return newNode;
}
nodeInfo *createPrintVarNode(char *varname) {
nodeInfo *newNode = malloc(sizeof(nodeInfo));
newNode->opperation = 6;
newNode->name = varname;
return newNode;
}
/**
*
* @params opperation value, see print struct for info
* @params int value to be printed
* @params string to be printed
*
*
*/
nodeInfo *createPrintStatement(int opperation, int value, char *string) {
nodeInfo *n = malloc(sizeof(nodeInfo));
print a;
//if we are going to print a varibles
//or we are going to print an int
switch(opperation) {
case 1:
n->opperation = 3;//this needs to not be a magic number lol
a.value = value;
a.opperation = 1;
n->printExpression = a;
return n;
break;
//else we are printing a string
case 2:
n->opperation = 3;
a.string = string;
a.opperation = 2;
n->printExpression = a;
return n;
break;
case 3:
n->opperation = 3;
a.string = string;
a.opperation = 3;
a.value = value;
n->printExpression = a;
return n;
break;
default:
printf("Something wrong with your print statement\n");
}
}
nodeInfo *createLogic(int opperation, int expr, nodeInfo *statement_list, nodeInfo *else_false) {
nodeInfo *n = malloc(sizeof(nodeInfo));
switch (opperation) {
//if statement
case 1:
//logical expression, see nodeInfo for opperation info
n->opperation = 4;
logic a;
a.opperation = 1;
a.expr = expr;
while (statement_list->statement_list != NULL) {
statement_list = statement_list->statement_list;
}
//now that we have the statement list, we need to make the head opperation 5
nodeInfo *newNode = malloc(sizeof(nodeInfo));
newNode->opperation = 5;
newNode->next = copyLinkedList(statement_list);
freeLinkedList(statement_list);
a.if_true = newNode;
//this removes the last statement list in statementHead
statement_list = NULL;
n->logicalExpression = a;
return n;
break;
//while loop
case 2:
/*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");
}
}
nodeInfo *createCompoundStatement(nodeInfo *n) {
if(statementHead == NULL) {
statementHead = malloc(sizeof(nodeInfo));
nodeInfo *newNode = malloc(sizeof(nodeInfo));
statementHead->opperation = 5;
statementHead->next = n;
statementHead->next->next = NULL;
statementHead->statement_list = NULL;
} else {
nodeInfo *p = statementHead;
//tereverse the list for the end
while(p->statement_list != NULL) {
p = p->statement_list;
}
p->next = malloc(sizeof(nodeInfo));
p->next = n;
p->next->next = NULL;
}
return statementHead;
}
/*
Adds statement to linked list.
@param nodeInfo link to be added.
@return head of linked list.
*/
nodeInfo *addToCompoundStatement(nodeInfo *n) {
if(statementHead == NULL) {
statementHead = malloc(sizeof(nodeInfo));
statementHead->opperation = 5;
statementHead->next = n;
statementHead->next->next = NULL;
statementHead->statement_list = NULL;
} else {
nodeInfo *p = statementHead;
while (p->statement_list != NULL) {
p = p->statement_list;
}
while (p->next != NULL) {
p = p->next;
}
p->next = malloc(sizeof(nodeInfo));
p->next = n;
p->next->next = NULL;
}
return statementHead;
}
/*
Executes a statment.
@param nodeInfo statement to be executed
@return void.
*/
//TODO return bool or int detailing the status of execution.
void ex(nodeInfo *n) {
switch(n->opperation){
case 1:
addVar(n->var->name, n->var->value);
break;
//TODO expression stuff
case 2:
break;
//print
case 3:
switch(n->printExpression.opperation) {
case 1:
printf("%d\n", (int) n->printExpression.value);
break;
case 2:
printf("%s\n", n->printExpression.string);
break;
case 3:
printf("%s%lf\n", n->printExpression.string, n->printExpression.value);
break;
default:
printf("something wrong with your if statement, check yacc file\n");
}
break;
//logic (if, while, for, etc)
case 4:
switch(n->logicalExpression.opperation) {
case 1:
if (n->logicalExpression.expr == 1) {
ex(n->logicalExpression.if_true);
}
break;
case 2:
while (n->logicalExpression.expr == 1) {
ex(n->logicalExpression.while_true);
}
break;
default:
printf("something wrong with logical expression check yacc\n");
}
break;
case 5:
while(n->next != NULL) {
n = n->next;
ex(n);
}
statementHead = NULL;
break;
case 6:
;
VariableValues *value = getValue(n->name);
switch(value->type) {
case STRINGVAR:
printf("%s\n", value->String);
break;
case INT:
printf("%d\n", value->Int);
break;
case CHARVAR:
printf("%c\n", value->Char);
break;
case DOUBLE:
printf("%f\n", value->Double);
break;
default:
printf("no such variable type called , keep coding!\n");
}
break;
default:
;
//TODO add error/exit here
switch(n->type) {
case FUNCTION_CALL:
;
nodeInfo *_stmts = *map_get(&*((map_void_t* ) _function_list), n->name);
while (_stmts->next != NULL) {
_stmts = _stmts->next;
ex(_stmts);
}
break;
case FUNCTION:
if (_function_list == NULL) {
_function_list = malloc(sizeof(map_void_t));
n->local_var_list = malloc(sizeof(map_void_t));
n->next = NULL;
n->local_list = NULL;
map_init(&*((map_void_t *) _function_list));
map_init(&*((map_void_t *) n->local_var_list));
map_set(&*((map_void_t* ) _function_list), n->name, &*n->_function_body);
} else {
map_set(&*((map_void_t* ) _function_list), n->name, &*n->_function_body);
}
break;
default:
;
//TODO add error here and close
}
}
}

@ -0,0 +1,24 @@
typedef struct assignment assignment;
typedef struct expression expression;
typedef struct print print;
typedef struct logic logic;
typedef struct nodeInfo nodeInfo;
nodeInfo *node(int opperation, char opper, char var, int l, int r);
nodeInfo *createFunctionCall(char *_name);
nodeInfo *createFunction(char *_name, nodeInfo *_stmts);
nodeInfo *createFunctionExpression(int lvalue, int rvalue, char opper);
nodeInfo *createVarAssignmentString(char *name, char *string);
nodeInfo *createVarAssignmentInt(char *name, int number);
nodeInfo *createVarAssignmentChar(char *name, char Char);
nodeInfo *createVarAssignmentDouble(char *name, double Double);
nodeInfo *createPrintVarNode(char *varname);
//TODO this doesnt belong here, make another folder/file for print
nodeInfo *createPrintStatement(int opperation, int value, char *string);
//TODO this doesnt belong here, make another folder/file for logic
nodeInfo *createLogic(int opperationm, int expr, nodeInfo *if_true, nodeInfo *else_false);
nodeInfo *createCompoundStatement(nodeInfo *n);
void ex(nodeInfo *n);
int evalExpression(expression *n);

@ -0,0 +1,144 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../hashmap/map.h"
/**
* VariableType is a enum of type struct that holds the varible types that will
* be inside of my language.
*/
typedef enum VariableType{
STRINGVAR,
INT,
CHARVAR,
DOUBLE
} VariableType;
/**
* VariableValues is a struct that holds all possible variable values
*/
typedef struct VariableValues{
VariableType type;
char Char;
char *String;
int Int;
double Double;
} VariableValues;
/**
* Variables is a struct that has all the information needed for a variables
*/
typedef struct Variable{
char *name;
VariableValues *value;
struct Variable *next;
} Variable;
//TODO this needs to be handled somewhere else. hashmap of all variables
struct map_void_t *varMap = NULL;
/**
*
* 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 addVar(char *name, VariableValues *values) {
if(varMap == NULL) {
varMap = malloc(sizeof(map_void_t));
map_init(&*((map_void_t *) varMap));
}
map_set(&*((map_void_t* ) varMap), name, &*values);
}
/**
* returns variables values from hashmap
*
* @see [VariableValues]
* @see [char *string]
* @return [VariableValues] containing variables data
* @param [char *string] Variable name.
*
*/
VariableValues *getValue(char *name) {
return *map_get(&*((map_void_t* ) varMap), 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* makeVariableInt(char *name, int Int) {
Variable *p = malloc(sizeof(Variable));
VariableValues *IntegerValue = malloc(sizeof(VariableValues));
IntegerValue->type = INT;
IntegerValue->Int = Int;
p->name = name;
p->value = IntegerValue;
return p;
}
Variable* makeVariableDouble(char *name, double Double) {
Variable *p = malloc(sizeof(Variable));
VariableValues *DoubleValue= malloc(sizeof(VariableValues));
DoubleValue->type = DOUBLE;
DoubleValue->Double = Double;
p->name = name;
p->value = DoubleValue;
return p;
}
Variable* makeVariableChar(char *name, char Char) {
Variable *p = malloc(sizeof(Variable));
VariableValues *CharacterValue = malloc(sizeof(VariableValues));
CharacterValue->type = CHARVAR;
CharacterValue->Char = Char;
p->name = name;
p->value = CharacterValue;
return p;
}
Variable* makeVariableString(char *name, char *String){
Variable *p = malloc(sizeof(Variable));
VariableValues *StringValue = malloc(sizeof(VariableValues));
StringValue->type = STRINGVAR;
StringValue->String = String;
p->name = name;
p->value = StringValue;
return p;
}

@ -0,0 +1,9 @@
#include "vars.c"
typedef enum VariableType VariableType;
typedef struct VariableValues VariableValues;
typedef struct Variable Variable;
//vars functions
void addVar(char *name, VariableValues *values);
VariableValues *getValue(char *name);
Loading…
Cancel
Save