Wow! finished function table, almost finished with lexing as a whole

This commit is contained in:
Aidan 2019-11-28 00:39:08 -08:00
parent bb070592a6
commit 8643824bb6
No known key found for this signature in database
GPG key ID: 327711E983899316
5 changed files with 97 additions and 116 deletions

BIN
pkg/shsh/.token.go.swp Normal file

Binary file not shown.

58
pkg/shsh/func_table.go Normal file
View file

@ -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
}

View file

@ -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
}

View file

@ -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 {}

View file

@ -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
}