commit c2411d97e9a9c103227d10174efc2e79e0057fd8 Author: john doe Date: Tue Sep 24 14:50:40 2019 -0700 V1.0 diff --git a/README.md b/README.md new file mode 100644 index 0000000..20d1662 --- /dev/null +++ b/README.md @@ -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! diff --git a/assign/assign.c b/assign/assign.c new file mode 100644 index 0000000..e69de29 diff --git a/assign/assign.h b/assign/assign.h new file mode 100644 index 0000000..e69de29 diff --git a/deon b/deon new file mode 100644 index 0000000..fb21d0c Binary files /dev/null and b/deon differ diff --git a/deon.l b/deon.l new file mode 100644 index 0000000..3771927 --- /dev/null +++ b/deon.l @@ -0,0 +1,85 @@ +%{ + #include + #include + #include + #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); +<> { 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; +} \ No newline at end of file diff --git a/deon.y b/deon.y new file mode 100644 index 0000000..04aa282 --- /dev/null +++ b/deon.y @@ -0,0 +1,121 @@ +%{ + +#include +#include +#include +#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 INTEGER +%token STRING VARNAME +%token CHAR +%token DOUBLEVAR +%type expr +%type 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); + +} + diff --git a/examples/functions.deon b/examples/functions.deon new file mode 100644 index 0000000..fc642a5 --- /dev/null +++ b/examples/functions.deon @@ -0,0 +1,9 @@ +i = 10; + +def a : + if [ {int} i > 4 ] : + i = {int} i - 1; + +call a; + +printf [ {int} i ]; \ No newline at end of file diff --git a/examples/logic.deon b/examples/logic.deon new file mode 100644 index 0000000..f793b78 --- /dev/null +++ b/examples/logic.deon @@ -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!" ]; \ No newline at end of file diff --git a/examples/newfunctions.deon b/examples/newfunctions.deon new file mode 100644 index 0000000..b2b2645 --- /dev/null +++ b/examples/newfunctions.deon @@ -0,0 +1,18 @@ +def AnotherFunction: { + + printf[ "another Function!" ]; + +}; + + +def Main : { + + if [ 10 > 4 ]: { + + printf[ "hello world" ]; + + }; + +}; + +call Main; diff --git a/examples/test.deon b/examples/test.deon new file mode 100644 index 0000000..6d790f7 --- /dev/null +++ b/examples/test.deon @@ -0,0 +1,11 @@ +def Main : { + + + printf["hello world"]; + a = 10; + printf[a]; + + +}; + +call Main; \ No newline at end of file diff --git a/examples/variables.deon b/examples/variables.deon new file mode 100644 index 0000000..1c3cec9 --- /dev/null +++ b/examples/variables.deon @@ -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 ]; \ No newline at end of file diff --git a/functions/functions.c b/functions/functions.c new file mode 100644 index 0000000..e69de29 diff --git a/functions/functions.h b/functions/functions.h new file mode 100644 index 0000000..e69de29 diff --git a/hashmap/map.c b/hashmap/map.c new file mode 100644 index 0000000..3f0b0b0 --- /dev/null +++ b/hashmap/map.c @@ -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 +#include +#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); +} \ No newline at end of file diff --git a/hashmap/map.h b/hashmap/map.h new file mode 100644 index 0000000..59758ab --- /dev/null +++ b/hashmap/map.h @@ -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 + +#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 \ No newline at end of file diff --git a/linkedlist/linked.c b/linkedlist/linked.c new file mode 100644 index 0000000..790cb6b --- /dev/null +++ b/linkedlist/linked.c @@ -0,0 +1,6 @@ +typedef struct link { + + + + +} link; \ No newline at end of file diff --git a/linkedlist/linked.h b/linkedlist/linked.h new file mode 100644 index 0000000..e69de29 diff --git a/logic/logic.c b/logic/logic.c new file mode 100644 index 0000000..22c0e25 --- /dev/null +++ b/logic/logic.c @@ -0,0 +1,17 @@ +typedef struct Logic { + + struct enum logicType { + + IF, + ELSE, + WHILE, + FOR + + } logicType; + + + +} Logic; + + +bool evalCondition() \ No newline at end of file diff --git a/logic/logic.h b/logic/logic.h new file mode 100644 index 0000000..2c26f21 --- /dev/null +++ b/logic/logic.h @@ -0,0 +1,5 @@ +#include "logic.c" +typedef struct enum Logic Logic; + +Logic *createLogic(LogicType type, LogicCondition *condition, nodeInfo *statementList); +bool condition(LogicCondition *condition); \ No newline at end of file diff --git a/logic/main.c b/logic/main.c new file mode 100644 index 0000000..8814c46 --- /dev/null +++ b/logic/main.c @@ -0,0 +1,9 @@ +#include "logic.h" +#include + +int main() { + + + + return 0; +} \ No newline at end of file diff --git a/make.sh b/make.sh new file mode 100644 index 0000000..d34918d --- /dev/null +++ b/make.sh @@ -0,0 +1,3 @@ +lex deon.l +yacc -d deon.y +gcc hashmap/map.c lex.yy.c y.tab.c -o deon diff --git a/networking/a.out b/networking/a.out new file mode 100644 index 0000000..677a51f Binary files /dev/null and b/networking/a.out differ diff --git a/networking/main.c b/networking/main.c new file mode 100644 index 0000000..bf7c74f --- /dev/null +++ b/networking/main.c @@ -0,0 +1,12 @@ +#include +#include "socket.h" + +int main() { + + Socket news = create_lsocket(5001, 5); + + printf("Created socket!\n"); + sleep(10); + + return 0; +} \ No newline at end of file diff --git a/networking/socket.h b/networking/socket.h new file mode 100644 index 0000000..8ed70f3 --- /dev/null +++ b/networking/socket.h @@ -0,0 +1,134 @@ +#include +#include +#include +#include +#include +#include + +/** + * + * 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; + + + } + + +} + + diff --git a/networking/socket.h.gch b/networking/socket.h.gch new file mode 100644 index 0000000..8fe9c25 Binary files /dev/null and b/networking/socket.h.gch differ diff --git a/networking/template.deon b/networking/template.deon new file mode 100644 index 0000000..6c25805 --- /dev/null +++ b/networking/template.deon @@ -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 = { + + + + + +} \ No newline at end of file diff --git a/networking/test.c b/networking/test.c new file mode 100644 index 0000000..d9147e2 --- /dev/null +++ b/networking/test.c @@ -0,0 +1,87 @@ +#include +#include +#include +#include +#include +#include + + +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; +} \ No newline at end of file diff --git a/parser/parser.c b/parser/parser.c new file mode 100644 index 0000000..ca31956 --- /dev/null +++ b/parser/parser.c @@ -0,0 +1,534 @@ +#include +#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 + + } + + + } + +} diff --git a/parser/parser.h b/parser/parser.h new file mode 100644 index 0000000..a80baa9 --- /dev/null +++ b/parser/parser.h @@ -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); \ No newline at end of file diff --git a/print/print.c b/print/print.c new file mode 100644 index 0000000..e69de29 diff --git a/print/print.h b/print/print.h new file mode 100644 index 0000000..e69de29 diff --git a/vars/vars.c b/vars/vars.c new file mode 100644 index 0000000..aa1e338 --- /dev/null +++ b/vars/vars.c @@ -0,0 +1,144 @@ +#include +#include +#include +#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; + +} diff --git a/vars/vars.h b/vars/vars.h new file mode 100644 index 0000000..950b156 --- /dev/null +++ b/vars/vars.h @@ -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); \ No newline at end of file