From 8643824bb6973cf253c698e347ee668dc5c35dd8 Mon Sep 17 00:00:00 2001 From: Aidan Date: Thu, 28 Nov 2019 00:39:08 -0800 Subject: [PATCH] Wow! finished function table, almost finished with lexing as a whole --- pkg/shsh/.token.go.swp | Bin 0 -> 12288 bytes pkg/shsh/func_table.go | 58 ++++++++++++++++++++++++++++++ pkg/shsh/parsers.go | 74 --------------------------------------- pkg/shsh/symbol_table.go | 32 ----------------- pkg/shsh/token.go | 49 ++++++++++++++++++++------ 5 files changed, 97 insertions(+), 116 deletions(-) create mode 100644 pkg/shsh/.token.go.swp create mode 100644 pkg/shsh/func_table.go delete mode 100644 pkg/shsh/parsers.go delete mode 100644 pkg/shsh/symbol_table.go diff --git a/pkg/shsh/.token.go.swp b/pkg/shsh/.token.go.swp new file mode 100644 index 0000000000000000000000000000000000000000..1cfe61818b3eee6835b97ee55fc1bad091789af7 GIT binary patch literal 12288 zcmeI2&5ImG7{)766HVMGiJ;)Ya)q7Q7-u#SaT!_6ZZ?sD$*j)KtO$`wr>Am;D4Zi@^-O{SjX;UEoYJ^e*Q-(eI`Zy z&<70FU_AI1+yK|Xr{EoM354Jk@H}`DJPhsz zcY$A~82bvm4=w@$Dxd@&1AD<9aPxk~z6W1`tKePm65xP=zxOltHTV#`4LV>AG{AB2 z5cq2!d;_0=kHKYd7Bs za0R>t-UO$>vw*a}2mH484h$gevQ|JVpcT*x{C5?&z&MgGROmbOh>FD`udghxlz6?f zQ@ihOa?kJs>9o1&12Y+~BBgJ+Hb5ufyLQMoh zrfBg6ZW(qUSlUQW>VSrs{9(!!9DH`zw*Yqr3~a?t(73)MRHEr$ z_R+T%IwEg&48L!L+GWsm!Y<}XGBY#094yPWR70Ix!ZJczmHHFW@RqP8jn45LqjH)C zoLk_^55?fXK`&|8XbsiIi&sV)lbmW)Pt?mRRYncjbb$+~$1@^iTYJH>ER--6Ut6q| z7ndq0S+*196En~@KRd}-)}LzQ^wP=NHf9n{C-{ZdK+zVD?tSW6cDB`etz3O!WHyR~ z$Pfki)<|<~p(!0FiY5w&Rpq1aP&iJOaOZuglvnE`6ZZ_JYso&d>pHPmsf>)KJ;=IV zh$5gL0%P|FI@mH$6BW%GM5l^4pU>(screJ_UgW%J1OYd==Sqi8r5h^lT4aD5PKyW1 z#SPJG9#~AgJ&{{OVGw)cxq(#Db>I)O14E+@sCUF>zE0m2_Z>71gnM-MCY{IGq4U_2 zCOV3=I7*S7Ts~J~Q8D?G9%{NR1{!)1JI2VFT_MU^+@d=SQuX{wJVjOiaE%L( zfqM$p`@J{d0-^((OQ$6$EQQi;;d^q@C>99a(`%2+aFl1#7ZjeHDl&U#g^n4;TAGGACMuBD-rr3(BQ6?RtSc!a~13~XK(L^q)p*KWgj;Yr@!DGvqD8#LY z3F7!kZ&6yEaGG>nq^pd`M0z!jYm09?9=%eA$HjNk_%^y7&@wU(v4FFhk6lfD!7@`n brxWF;ne2M_njc-6XPD~-wx2$_e~$eFw%}-= literal 0 HcmV?d00001 diff --git a/pkg/shsh/func_table.go b/pkg/shsh/func_table.go new file mode 100644 index 0000000..50821d5 --- /dev/null +++ b/pkg/shsh/func_table.go @@ -0,0 +1,58 @@ +package shsh + +import ( + "strings" +) + +type Operation func(*Token) *Token + +type Function struct { + func operation + timesCalled int + args int +} + +type FuncTable map[string]*Function + +var ( + GlobalFuncTable *FuncTable +) + +// TODO: Currently only checks arg list length +func ParseFunction(target *Function, args *Token) bool { + // HANDLE EXEC + if target.args < 0 { + return true + } + + i := target.args + for iter = &args; *iter; iter = &(*iter.next) { + i -= 1 + } + + if i != 0 { + // log error here? + return false + } + + return true +} + +func CallFunction(target *Function, args *Token) *Token { + if !ParseFunction(target, args) { + return args + } + + target.timesCalled += 1 + return target.operation(args) +} + +func GetFunction(string arg) *Function { + target, ok := GlobalFuncTable[arg] + if !ok { + // TODO: hook into stdlib exec call + ; + } + + return target +} diff --git a/pkg/shsh/parsers.go b/pkg/shsh/parsers.go deleted file mode 100644 index 4e8ca51..0000000 --- a/pkg/shsh/parsers.go +++ /dev/null @@ -1,74 +0,0 @@ -package shsh - -import ( - "strings" - "unicode" -) - -/* - * LIST: a list of elements - * OPERAND: a string or number - * OPERATOR: an entry in a symtable - * OPERATION: a list starting with an operator - */ -type parse_tag int -const ( - LIST_T parse_tag = iota - SYMBOL_T parse_tag = iota - OPERAND_T parse_tag = iota - OPERATION_T parse_tag = iota -) - -func Parse(arg *Token) { - switch arg.tag { - case LIST_T: - for i := arg; i; i = i.next { - Parse(i) - } - - if list_is_operation(arg) { - arg.tag = OPERATION_T - } - - case OPERAND_T: - if string_is_symbol(arg._inner) { - arg.tag = SYMBOL_T - } - - default: - ;// TODO: Tag a parse error? - } -} - -func string_delimiters_valid(arg string) bool { - delim := arg[0] - iter := 0 - - if delim != arg[len(arg) - 1] { - return false - } - - for _, r := range arg { - if delim == r { - iter += 1 - } - } - - return iter == 2 -} - -func list_is_operation(arg *Token) bool { - // TODO: Rewrite after implementing a symbol table - //return ((*Token) arg._inner).tag == OPERATOR_T -} - -// theres probly a way better way to do it. -func string_is_symbol(arg string) bool { - for _, r := range arg { - if !unicode.IsLetter(r) && r != '_' { - return false - } - } - - return true -} diff --git a/pkg/shsh/symbol_table.go b/pkg/shsh/symbol_table.go deleted file mode 100644 index 4ec12a8..0000000 --- a/pkg/shsh/symbol_table.go +++ /dev/null @@ -1,32 +0,0 @@ -package shsh - -import ( - "strings" -) - -type operation func(*Token) *Token -type symbol_tag int -const ( - SYM_OPERATOR symbol_tag = iota, - SYM_VARIABLE symbol_tag = iota -) - -type bucket struct { - symbol string - tag symbol_tag - _inner interface{} -} - -type sym_table []bucket -const initial_table_length 10 -var ( - global_sym_table sym_table -) - -func extend_table() {} - -// TODO: take in a table as a target, so that inner scopes can be appended to outer scopes -func set_variable(key string, val string) {} -func get_variable(arg string) string {} -func set_operator(key string, val operation) {} -func get_operator(arg string) operation {} diff --git a/pkg/shsh/token.go b/pkg/shsh/token.go index 79cd1e6..a66db93 100644 --- a/pkg/shsh/token.go +++ b/pkg/shsh/token.go @@ -4,24 +4,37 @@ import ( "strings" ) +type token_t int +const ( + LIST token_t = iota + STRING token_t = iota + NUMBER token_t = iota + VARIABLE token_t = iota + FUNCTION token_t = iota +) + type Token struct { next *Token tag parse_tag + int position _inner interface{} } -func Lex(input string) Token { +func Lex(input string) *Token { ret := new(Token) iter := &ret delim := ' ' var tok strings.Builder iter_alloced := false - is_list = false; + is_list = false + is_str = false + is_num = true for pos, char := range input { switch char { // TODO: User configurable delimiters case '\'', '"', '`': + is_str = true delim = char case '(': is_list = true @@ -29,22 +42,41 @@ func Lex(input string) Token { case delim: *iter = new(Token) + *iter.position = pos + if is_list { // TODO: Pass a pointer out of Lex and store a pointer *iter._inner = Lex(tok.String()) - *iter.tag = LIST_T is_list = false + if (*iter._inner.tag == FUNCTION) { + *iter.tag = CALL + } else { + *iter.tag = LIST + } + } else { - // TODO: Store a pointer to the contents of the stringbuilder *iter._inner = tok.String() - *iter.tag = OPERAND_T + if is_string { + *iter.tag = STRING + is_str = false + + } else if is_num { + *iter.tag = NUMBER + + } else if () { + // TODO: Detect VARIABLE + + } else { + *iter.tag = FUNCTION + } } iter_alloced = true delim = ' ' default: + is_num = is_num && IsDigit(char) tok.WriteRune(char) } @@ -54,10 +86,7 @@ func Lex(input string) Token { tok.Reset() } } -} -func eval(Token *tree) *Token { - // Find operations - // Simplify operations deepest first - // return tree of final Tokens + // TODO: Throw parsing error here if there is leftover in tok + return ret }