diff options
author | Peter Mikkelsen <petermikkelsen10@gmail.com> | 2022-01-08 22:45:00 +0000 |
---|---|---|
committer | Peter Mikkelsen <petermikkelsen10@gmail.com> | 2022-01-08 22:45:00 +0000 |
commit | 1ef3119fe613823a2145126c58948361ca7d3cd8 (patch) | |
tree | 5252d957ae512e1a727c9dec2b31e7b2a1d63e56 | |
parent | 214cdacca02552649d63f9045fdb8a17cfbb6fca (diff) |
Add initial code, just to get started
-rw-r--r-- | apl9.h | 65 | ||||
-rw-r--r-- | array.c | 29 | ||||
-rw-r--r-- | eval.c | 15 | ||||
-rw-r--r-- | lexer.c | 65 | ||||
-rw-r--r-- | main.c | 62 | ||||
-rw-r--r-- | mkfile | 16 | ||||
-rw-r--r-- | print.c | 25 |
7 files changed, 277 insertions, 0 deletions
@@ -0,0 +1,65 @@ +/* Global definitions of limits and constants */ +#define MAX_LINE_LENGTH 1024 +#define MAX_LINE_TOKENS 1024 + +typedef enum +{ + ArrayTag, + FunctionTag, + HybridTag, + MonadicOpTag, + DyadicOpTag, + BoundFunctionTag, /* Function with left arg bound */ + LParTag, + RParTag, + LCurlTag, + RCurlTag, + LBracketTag, + RBracketTag +} datumTag; + +typedef enum +{ + AtypeInt +} arrayDataType; + +/* Data types */ +typedef struct Array Array; +typedef struct Datum Datum; + +struct Array +{ + arrayDataType type; + int rank; + int *shape; + union { + char *rawdata; + vlong *intdata; + }; +}; + +struct Datum +{ + datumTag tag; + Rune *strrep; + union { + Array *array; + }; +}; + +/* Function prototypes for the different source files */ +/* print.c */ +Rune *ppdatum(Datum); +Rune *ppdatums(Datum *, int); + +/* lexer.c */ +Datum *lexline(Rune *, int *); + +/* array.c */ +Array *mkscalarint(vlong); + +/* eval.c */ +Datum *eval(Datum *, int *); + +/* Global variables */ +Rune *errormsg; /* eval.c */
\ No newline at end of file @@ -0,0 +1,29 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +#include "apl9.h" + +int datasizes[] = { + [AtypeInt] = sizeof(vlong) +}; + +Array * +mkarray(arrayDataType t, int rank, int size) +{ + Array *a = malloc(sizeof(Array)); + a->rank = rank; + a->shape = malloc(sizeof(int) * rank); + a->rawdata = malloc(datasizes[t] * size); + a->type = t; + return a; +} + +Array * +mkscalarint(vlong i) +{ + Array *a = mkarray(AtypeInt, 0, 1); + a->intdata[0] = i; + + return a; +}
\ No newline at end of file @@ -0,0 +1,15 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +#include "apl9.h" + +Rune *errormsg; + +Datum * +eval(Datum *tokens, int *ntoks) +{ + *ntoks = 0; + errormsg = L"Evaluator not written yet"; + return tokens; +}
\ No newline at end of file @@ -0,0 +1,65 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +#include "apl9.h" + +Rune primfuncnames[] = L"+-×÷*⍟⌹○!?|⌈⌊⊥⊤⊣⊢=≠≤<>≥≡≢∨∧⍲⍱↑↓⊂⊃⊆⌷⍋⍒⍳⍸∊⍷∪∩~,⍪⍴⌽⊖⍉⍎⍕"; +Rune primmonopnames[] = L"¨⍨⌸⌶&"; +Rune primdyadopnames[] = L"⍣.∘⍤⍥@⍠⌺"; +Rune primhybridnames[] = L"/\⌿⍀"; + +Datum * +lexline(Rune *line, int *ntoks) +{ + int offset = 0; + int len = runestrlen(line); + Datum *tokens = mallocz(sizeof(Datum) * MAX_LINE_TOKENS, 1); + *ntoks = 0; + while(offset < len){ + if(isspacerune(line[offset])){ + offset++; + continue; + }else if(runestrchr(L"(){}[]", line[offset])){ + switch(line[offset]){ + case '(': tokens[*ntoks].tag = LParTag; break; + case ')': tokens[*ntoks].tag = RParTag; break; + case '{': tokens[*ntoks].tag = LCurlTag; break; + case '}': tokens[*ntoks].tag = RCurlTag; break; + case '[': tokens[*ntoks].tag = LBracketTag; break; + case ']': tokens[*ntoks].tag = RBracketTag; break; + } + tokens[*ntoks].strrep = runesmprint("%C", line[offset]); + offset++; + }else if(runestrchr(primfuncnames, line[offset])){ + tokens[*ntoks].tag = FunctionTag; + tokens[*ntoks].strrep = runesmprint("%C", line[offset]); + offset++; + }else if(runestrchr(primmonopnames, line[offset])){ + tokens[*ntoks].tag = MonadicOpTag; + tokens[*ntoks].strrep = runesmprint("%C", line[offset]); + offset++; + }else if(runestrchr(primdyadopnames, line[offset])){ + tokens[*ntoks].tag = DyadicOpTag; + tokens[*ntoks].strrep = runesmprint("%C", line[offset]); + offset++; + }else if(isdigitrune(line[offset])){ + char buf[64]; + char *p = buf; + while(isdigitrune(line[offset])){ + p += runetochar(p, &line[offset]); + offset++; + } + *p = 0; + tokens[*ntoks].tag = ArrayTag; + tokens[*ntoks].array = mkscalarint(atoll(buf)); + tokens[*ntoks].strrep = runesmprint("%s", buf); + }else{ + print("Can't lex: %S\n", &line[offset]); + *ntoks = 0; + break; + } + (*ntoks)++; + } + return tokens; +}
\ No newline at end of file @@ -0,0 +1,62 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +#include "apl9.h" + +Rune *prompt(Rune *); +Datum *evalline(Rune *); + +Biobuf *stdin; + +void +main(void) +{ + int off = 0; + stdin = Bfdopen(0, OREAD); + + while(!off){ + Rune *input = prompt(L"\t"); + Datum *result = evalline(input); + if(result == nil){ + if(errormsg == nil) + off = 1; + else + print("ERROR: %S\n", errormsg); + }else{ + ppdatum(*result); + free(result); + } + } + exits(nil); +} + +Rune * +prompt(Rune *pr) +{ + Rune line[MAX_LINE_LENGTH]; + + print("%S",pr); + + int i = 0; + line[0] = 0; + while(i == 0 || line[i-1] != '\n') + line[i++] = Bgetrune(stdin); + line[i-1] = 0; + return runestrdup(line); +} + +Datum * +evalline(Rune *line) +{ + int ntoks; + Datum *tokens = lexline(line, &ntoks); + print("Evaluating line (n=%d): %S\n", ntoks, ppdatums(tokens, ntoks)); + Datum *result = eval(tokens, &ntoks); + if(ntoks == 1) + return result; + else{ + free(tokens); + return nil; + } +}
\ No newline at end of file @@ -0,0 +1,16 @@ +</$objtype/mkfile + +TARG=apl9 +OFILES=\ + main.$O\ + lexer.$O\ + eval.$O\ + print.$O\ + array.$O\ + +HFILES=\ + apl9.h\ + +BIN=/$objtype/bin + +</sys/src/cmd/mkone @@ -0,0 +1,25 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +#include "apl9.h" + +Rune * +ppdatum(Datum d) +{ + return runestrdup(d.strrep); +} + +Rune * +ppdatums(Datum *ds, int n) +{ + int i; + Rune *res = runesmprint(""); + Rune *tmp; + for(i = 0; i < n; i++){ + tmp = res; + res = runesmprint("%S %S", res, ppdatum(ds[i])); + free(tmp); + } + return res; +}
\ No newline at end of file |