diff options
| author | Kai Stevenson <kai@kaistevenson.com> | 2023-02-14 02:02:50 -0800 |
|---|---|---|
| committer | Kai Stevenson <kai@kaistevenson.com> | 2023-02-14 02:02:50 -0800 |
| commit | 24f981233bc3e0b000acf4615d4bc6f2332eefb0 (patch) | |
| tree | b036a7d937f8444d326355cbe07eea70df693c59 | |
init
| -rw-r--r-- | .gitignore | 5 | ||||
| -rw-r--r-- | Makefile | 11 | ||||
| -rw-r--r-- | README | 1 | ||||
| -rw-r--r-- | example.pcdt | 3 | ||||
| -rw-r--r-- | hashtable.c | 34 | ||||
| -rw-r--r-- | hashtable.h | 18 | ||||
| -rw-r--r-- | parse.c | 103 | ||||
| -rw-r--r-- | parse.h | 29 | ||||
| -rwxr-xr-x | precedent | bin | 0 -> 28848 bytes | |||
| -rw-r--r-- | precedent.c | 11 | ||||
| -rw-r--r-- | precedent.h | 8 | ||||
| -rw-r--r-- | scope.c | 20 | ||||
| -rw-r--r-- | scope.h | 13 |
13 files changed, 256 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d77bb67 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +a.out +a.exe +*.swp +snake3 +*.core diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a9b5503 --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +CFLAGS=-I. -pthread -Wall -Wextra -Wpedantic -std=c99 -march=native -O3 -lm +CFLAGS+= -Wshadow -Wstrict-prototypes -Wundef -Wpointer-arith -Wcast-align -Wstrict-overflow=5 -Wswitch-default +CFLAGS+= -Wunreachable-code -Wswitch-enum -Wformat=2 -g +PREFIX ?= /usr +BINDIR ?= ${PREFIX}/bin + +generate: + $(CC) -o precedent precedent.c hashtable.c scope.c parse.c $(CFLAGS) + +clean: + rm precedent @@ -0,0 +1 @@ +Attempt to make a programming language of some sort diff --git a/example.pcdt b/example.pcdt new file mode 100644 index 0000000..6c4dd92 --- /dev/null +++ b/example.pcdt @@ -0,0 +1,3 @@ +store(5; myVar;); +print(read(myVar;);); +(hello; hello2;) diff --git a/hashtable.c b/hashtable.c new file mode 100644 index 0000000..ce4c65a --- /dev/null +++ b/hashtable.c @@ -0,0 +1,34 @@ +#include <stdlib.h> +#include "hashtable.h" + +const unsigned int fnvPrime = 16777619; +const unsigned int fnvOffset = 2166136261U; + +//FNV-1a hash +unsigned int get_hash(char* str) { + unsigned int hash = fnvOffset; + while (*str != '\0') { + hash = (hash ^ *str) * fnvPrime; + str++; + } + return hash; +} +hashtable_t* init_hashtable(unsigned int capacity) { + hashtable_t* ht = malloc(sizeof(hashtable_t)); + ht->pairs = calloc(capacity, sizeof(pair_t*)); + ht->capacity = capacity; + return ht; +} +/* TODO: handle collision +TODO: return 0 if something goes wrong */ +unsigned int hashtable_add_pair(hashtable_t* hashtable, pair_t pair) { + unsigned int hash = get_hash(pair.key); + pair_t* memPair = malloc(sizeof(pair_t)); + *memPair = pair; + hashtable->pairs[hash % hashtable->capacity] = memPair; + return hash; +} +pair_t* hashtable_get_pair(hashtable_t* hashtable, char* key) { + unsigned int hash = get_hash(key); + return hashtable->pairs[hash % hashtable->capacity]; +} diff --git a/hashtable.h b/hashtable.h new file mode 100644 index 0000000..be45964 --- /dev/null +++ b/hashtable.h @@ -0,0 +1,18 @@ +#ifndef HASHTABLE +#define HASHTABLE + +typedef struct HashPair { + char* key; + void* value; +} pair_t; +typedef struct HashTable { + pair_t** pairs; + int capacity; + int itemCount; +} hashtable_t; +unsigned int get_hash(char* str); +hashtable_t* init_hashtable(unsigned int capacity); +unsigned int hashtable_add_pair(hashtable_t* hashtable, pair_t pair); +pair_t* hashtable_get_pair(hashtable_t* hashtable, char* key); + +#endif @@ -0,0 +1,103 @@ +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <stdio.h> +#include "parse.h" +#include "hashtable.h" + +void symbol_add_arg(sym_t* symbol, sym_t* arg) { + symbol->argCount += 1; + if (symbol->argCount == 1) { + symbol->args = malloc(sizeof(sym_t*)); + } + else { + symbol->args = realloc(symbol->args, symbol->argCount * (sizeof(sym_t*))); + } + (symbol->args)[symbol->argCount - 1] = arg; +} +void symset_add_symbol(symset_t* symbolSet, sym_t* symbol) { + symbolSet->count += 1; + if (symbolSet->count == 1) { + symbolSet->symbols = malloc(sizeof(sym_t*)); + } + else { + symbolSet->symbols = realloc(symbolSet->symbols, symbolSet->count * (sizeof(sym_t*))); + } + (symbolSet->symbols)[symbolSet->count - 1] = symbol; +} +symset_t* parse_symbols(char** str) { + symset_t* symbolSet = malloc(sizeof(symset_t)); + symbolSet->count = 0; + while (1) { + /* clear whitespace */ + while (!isalnum(**str) && **str != '(' && **str != ')' && **str != '\0') { + (*str)++; + } + if (**str == ')') { + (*str)++; + if (**str == ';') { + (*str)++; + return symbolSet; + } + } + else if (**str == '\0') { + return symbolSet; + } + char* symbolName = calloc(30, sizeof(char)); + int i = 0; + while (1) { + symbolName[i] = **str; + if (**str == ',' || **str == ';') { + (*str)++; + symbolName[i] = '\0'; + sym_t* symbol = malloc(sizeof(sym_t)); + symbol->province = LITERAL; + symbol->name = symbolName; + symbol->argCount = 0; + symset_add_symbol(symbolSet, symbol); + break; + } + else if (**str == '(') { + (*str)++; + symbolName[i] = '\0'; + sym_t* symbol = malloc(sizeof(sym_t)); + symbol->province = KEY_REF; + if(i > 1) { + symbol->name = symbolName; + } + else { + symbol->name = "fork"; + } + symset_t* symbols = parse_symbols(str); + for (int s = 0; s < symbols->count; s++) { + symbol_add_arg(symbol, symbols->symbols[s]); + } + symset_add_symbol(symbolSet, symbol); + break; + } + i++; + (*str)++; + } + } +} +sym_t* parse_symbol_final(char* str) { + char** strp = malloc(sizeof(char**)); + *strp = str; + symset_t* finalSymset = parse_symbols(strp); + sym_t* root = malloc(sizeof(sym_t)); + root->name = "root"; + root->province = KEY_REF; + for (int s = 0; s < finalSymset->count; s++) { + symbol_add_arg(root, finalSymset->symbols[s]); + } + return root; +} +void write_symbol_visual(sym_t* symbol, int offset) { + for (int o = 0; o < offset; o++) { + printf(" "); + } + printf("%s (%s)\n", (char*)(symbol->name), symbol->province == 1 ? "KEY" : "LITERAL"); + for (int i = 0; i < symbol->argCount; i++) { + write_symbol_visual(symbol->args[i], offset + 4); + } +} @@ -0,0 +1,29 @@ +#ifndef PARSE +#define PARSE + +/* keyword hashes */ +#define VAR_H 2317739966u +#define DEFINE_H 1788839250 + +typedef enum SymbolProvince { + NO_PROVINCE, + KEY_REF, + LITERAL +} prov_t; +typedef struct Symbol { + prov_t province; + void* name; + struct Symbol** args; + int argCount; +} sym_t; +typedef struct SymbolSet { + sym_t** symbols; + int count; +} symset_t; +void symbol_add_arg(sym_t* symbol, sym_t* arg); +void symset_add_symbol(symset_t* symbolSet, sym_t* symbol); +symset_t* parse_symbols(char** str); +sym_t* parse_symbol_final(char* str); +void write_symbol_visual(sym_t* symbol, int offset); + +#endif diff --git a/precedent b/precedent Binary files differnew file mode 100755 index 0000000..cc1fba2 --- /dev/null +++ b/precedent diff --git a/precedent.c b/precedent.c new file mode 100644 index 0000000..df7ac33 --- /dev/null +++ b/precedent.c @@ -0,0 +1,11 @@ +#include <stdlib.h> +#include <stdio.h> +#include "precedent.h" +#include "hashtable.h" +#include "parse.h" + +int main() { + sym_t* finalSymbol = parse_symbol_final("store(5; test;); print(read(test;);); (hello; hello2;);"); + write_symbol_visual(finalSymbol, 0); + return 0; +} diff --git a/precedent.h b/precedent.h new file mode 100644 index 0000000..4449f83 --- /dev/null +++ b/precedent.h @@ -0,0 +1,8 @@ +#include "parse.h" +#ifndef PRECEDENT +#define PRECEDENT + +void execute_imperative(sym_t symbol); +void* eval_symbol(sym_t symbol); + +#endif @@ -0,0 +1,20 @@ +#include <stdlib.h> +#include "scope.h" +#include "hashtable.h" + +scope_t* init_scope(scope_t parent) { + scope_t* scope = malloc(sizeof(scope_t)); + scope->hashtable = init_hashtable(1000); + *(scope->parent) = parent; + return scope; +} +pair_t* get_pair_global(char* key, scope_t* scope) { + while (scope->parent != NULL) { + pair_t* pair = hashtable_get_pair(scope->hashtable, key); + if (pair != NULL) { + return pair; + } + scope = scope->parent; + } + return NULL; +} @@ -0,0 +1,13 @@ +#include "hashtable.h" +#ifndef SCOPE +#define SCOPE + +typedef struct Scope { + hashtable_t* hashtable; + struct Scope* parent; +} scope_t; +scope_t* init_scope(scope_t parent); +pair_t* get_pair_global(char* key, scope_t* scope); +pair_t* get_pair_local(char* key, scope_t* scope); + +#endif |
