Wow! finished function table, almost finished with lexing as a whole
This commit is contained in:
parent
bb070592a6
commit
8643824bb6
5 changed files with 97 additions and 116 deletions
BIN
pkg/shsh/.token.go.swp
Normal file
BIN
pkg/shsh/.token.go.swp
Normal file
Binary file not shown.
58
pkg/shsh/func_table.go
Normal file
58
pkg/shsh/func_table.go
Normal 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
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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 {}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue