It builds

This commit is contained in:
Aidan Hahn 2019-11-28 20:07:28 -08:00
parent 7aa80376bb
commit 7e175dec95
No known key found for this signature in database
GPG key ID: 327711E983899316
7 changed files with 52 additions and 45 deletions

View file

@ -0,0 +1,14 @@
package main
import (
"bufio"
"os"
"shsh"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
PrintSExpression(Lex(scanner.Text()))
}
}

Binary file not shown.

View file

@ -2,6 +2,7 @@ package shsh
import ( import (
"strings" "strings"
"fmt"
) )
func FmtToken(arg *Token) string { func FmtToken(arg *Token) string {
@ -12,11 +13,11 @@ func FmtToken(arg *Token) string {
switch arg.tag { switch arg.tag {
case LIST: case LIST:
return sprintf("(%s, List @ %p, %d)%s", "LIST", arg._inner, return fmt.Sprintf("(%s, List @ %p, %d)%s", "LIST", arg._inner,
arg.position, suffix) arg.position, suffix)
default: default:
return sprintf("(%s, %s, %d)%s", GetTagAsStr(arg.tag), arg._inner, return fmt.Sprintf("(%s, %s, %d)%s", GetTagAsStr(arg.tag), arg._inner,
arg.position, suffix) arg.position, suffix)
} }
} }
@ -32,26 +33,24 @@ func GetTagAsStr(tag token_t) string {
case SYMBOL: case SYMBOL:
return "SYMBOL" return "SYMBOL"
} }
return "UNKNOWN"
} }
func PrintSExpression(arg *Token) { func PrintSExpression(arg *Token) {
var lists Stack; var lists TokenStack;
lists.push(arg) lists.Push(arg)
loop: loop:
var constructor strings.Builder var constructor strings.Builder
i := lists.pop() i := lists.Pop()
if i == nil { if i == nil {
goto done return
} }
for (iter := i; iter != nil; iter = i.next { for iter := i; iter != nil; iter = i.next {
constructor.WriteString(FmtToken(iter)) constructor.WriteString(FmtToken(iter))
} }
print(constructor.String()) print(constructor.String())
goto loop goto loop
done:
// TODO: Perhaps print some debug analytics here
} }

View file

@ -1,13 +1,9 @@
package shsh package shsh
import (
"strings"
)
type Operation func(*Token) *Token type Operation func(*Token) *Token
type Function struct { type Function struct {
func operation function Operation
timesCalled int timesCalled int
args int args int
} }
@ -26,7 +22,7 @@ func ParseFunction(target *Function, args *Token) bool {
} }
i := target.args i := target.args
for iter = &args; *iter; iter = &(*iter.next) { for iter := &args; *iter != nil; iter = &((*iter).next) {
i -= 1 i -= 1
} }
@ -44,11 +40,11 @@ func CallFunction(target *Function, args *Token) *Token {
} }
target.timesCalled += 1 target.timesCalled += 1
return target.operation(args) return target.function(args)
} }
func GetFunction(string arg) *Function { func GetFunction(arg string) *Function {
target, ok := GlobalFuncTable[arg] target, ok := (*GlobalFuncTable)[arg]
if !ok { if !ok {
// TODO: hook into stdlib exec call // TODO: hook into stdlib exec call
; ;

View file

@ -2,21 +2,21 @@ package shsh
type TokenStack struct { type TokenStack struct {
buffer []*Token buffer []*Token
int capacity capacity int
} }
func (s *Stack) Push(v *Token) { func (s *TokenStack) Push(v *Token) {
s.capacity++ s.capacity++
*s.buffer = append(*s.buffer, v) s.buffer = append(s.buffer, v)
} }
func (s *Stack) Pop() *Token { func (s *TokenStack) Pop() *Token {
if s.capacity <= 0 { if s.capacity <= 0 {
return nil return nil
} }
s.capacity-- s.capacity--
res := *s.buffer[len(*s.buffer) - 1] res := s.buffer[len(s.buffer) - 1]
*s = *s.buffer[ :len(*s) - 1] s.buffer = s.buffer[:len(s.buffer) - 1]
return ret return res
} }

View file

@ -2,6 +2,7 @@ package shsh;
import ( import (
"strings" "strings"
"unicode"
) )
type token_t int type token_t int
@ -15,7 +16,7 @@ const (
type Token struct { type Token struct {
next *Token next *Token
tag token_t tag token_t
int position position int
_inner interface{} _inner interface{}
} }
@ -25,9 +26,9 @@ func Lex(input string) *Token {
delim := ' ' delim := ' '
var tok strings.Builder var tok strings.Builder
iter_alloced := false iter_alloced := false
is_list = false is_list := false
is_str = false is_str := false
is_num = true is_num := true
for pos, char := range input { for pos, char := range input {
switch char { switch char {
@ -41,24 +42,24 @@ func Lex(input string) *Token {
case delim: case delim:
*iter = new(Token) *iter = new(Token)
*iter.position = pos (*iter).position = pos
if is_list { if is_list {
*iter._inner = Lex(tok.String()) (*iter)._inner = Lex(tok.String())
is_list = false is_list = false
*iter._inner = LIST (*iter)._inner = LIST
} else { } else {
*iter._inner = tok.String() (*iter)._inner = tok.String()
if is_string { if is_str {
*iter.tag = STRING (*iter).tag = STRING
is_str = false is_str = false
} else if is_num { } else if is_num {
*iter.tag = NUMBER (*iter).tag = NUMBER
} else { } else {
*iter.tag = SYMBOL (*iter).tag = SYMBOL
} }
} }
@ -66,12 +67,12 @@ func Lex(input string) *Token {
delim = ' ' delim = ' '
default: default:
is_num = is_num && IsDigit(char) is_num = is_num && unicode.IsDigit(char)
tok.WriteRune(char) tok.WriteRune(char)
} }
if iter_alloced { if iter_alloced {
iter = &(*iter.next) iter = &((*iter).next)
iter_alloced = false iter_alloced = false
tok.Reset() tok.Reset()
} }

View file

@ -1,9 +1,5 @@
package shsh package shsh
import (
"strings"
)
type VarTable map[string]*Token type VarTable map[string]*Token
var ( var (
@ -13,9 +9,10 @@ var (
// Library represents variables defined in inner scope // Library represents variables defined in inner scope
// It is assumed library is ordered from innermost scope to outermost scope // It is assumed library is ordered from innermost scope to outermost scope
func GetVar(arg string, library []VarTable) *Token { func GetVar(arg string, library []VarTable) *Token {
for dict, scope := library { for scope, dict := range library {
val, ok := dict[arg] val, ok := dict[arg]
if ok { if ok {
scope = scope // TEMP LINE
// TODO: maybe log which scope it was found in? // TODO: maybe log which scope it was found in?
return val return val
} }