integrate environment variables with vartable
This commit is contained in:
parent
9301c77573
commit
7c04e3de95
4 changed files with 57 additions and 4 deletions
|
|
@ -68,7 +68,7 @@ func Lex(input string) *Token {
|
|||
(*iter).Tag = STRING
|
||||
is_str = false
|
||||
|
||||
} else if tokenIsNumber(tok) {
|
||||
} else if StrIsNumber(tok) {
|
||||
(*iter).Tag = NUMBER
|
||||
|
||||
} else {
|
||||
|
|
@ -181,7 +181,7 @@ error:
|
|||
return nil
|
||||
}
|
||||
|
||||
func tokenIsNumber(arg string) bool {
|
||||
func StrIsNumber(arg string) bool {
|
||||
dotCount := 0
|
||||
|
||||
for _, char := range arg {
|
||||
|
|
@ -196,3 +196,4 @@ func tokenIsNumber(arg string) bool {
|
|||
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,17 +17,42 @@
|
|||
|
||||
package ast
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
"git.callpipe.com/aidan/shs/log"
|
||||
)
|
||||
|
||||
type VarTable *map[string]*Token
|
||||
|
||||
func GetVar(arg string, vt VarTable) *Token {
|
||||
val, ok := (*vt)[arg]
|
||||
if !ok {
|
||||
return nil
|
||||
e := os.Getenv(arg)
|
||||
if e != "" {
|
||||
t := &Token{Inner: e}
|
||||
if StrIsNumber(e) {
|
||||
t.Tag = NUMBER
|
||||
} else {
|
||||
t.Tag = STRING
|
||||
}
|
||||
|
||||
SetVar(arg, t, vt)
|
||||
return t
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
// TODO: Document me :)
|
||||
func SetVar(variable string, value *Token, vt VarTable) {
|
||||
(*vt)[variable] = value
|
||||
if value.Tag == NUMBER || value.Tag == STRING {
|
||||
os.Setenv(variable, value.Inner.(string))
|
||||
}
|
||||
}
|
||||
|
||||
// Library represents variables defined in inner scope
|
||||
// It is assumed library is ordered from innermost scope to outermost scope
|
||||
func GetVarFromTables(arg string, library []VarTable) *Token {
|
||||
|
|
@ -43,3 +68,29 @@ func GetVarFromTables(arg string, library []VarTable) *Token {
|
|||
|
||||
return res
|
||||
}
|
||||
|
||||
func InitVarTable(table VarTable) {
|
||||
for _, val := range os.Environ() {
|
||||
variable := strings.Split(val, "=")
|
||||
t := &Token{Inner: variable[1]}
|
||||
if StrIsNumber(variable[1]) {
|
||||
t.Tag = NUMBER
|
||||
} else {
|
||||
t.Tag = STRING
|
||||
}
|
||||
|
||||
SetVar(variable[0], t, table)
|
||||
}
|
||||
}
|
||||
|
||||
// Dont do this on var tables youve already called InitVarTable on.... please....
|
||||
// This will pull currently contained variables OUT of the operating env
|
||||
func DeleteVarTable(table VarTable) {
|
||||
for key, _ := range (*table) {
|
||||
// from what I can tell, theres not much we can do if this fails
|
||||
err := os.Unsetenv(key)
|
||||
if err != nil {
|
||||
log.Log(log.DEBUG, "Failed to remove " + key + " from env: " + err.Error(), "vartable")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ func main() {
|
|||
|
||||
funcs = stdlib.GenFuncTable()
|
||||
vars = &map[string]*ast.Token{}
|
||||
ast.InitVarTable(vars)
|
||||
|
||||
useHist := false
|
||||
var histFile *os.File
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ The standard library is loaded during the init step of the repl (or interpreter
|
|||
|
||||
## Working with Tokens
|
||||
[Tokens](https://git.callpipe.com/aidan/shs/-/blob/master/ast/token.go) are a rudimentary linked list of parsed [Lexemes](https://en.wikipedia.org/wiki/Lexeme). In the ast package there are definitions for Tokens, as well as code for the combined Lex/Parse loop that creates them. Tokens are built in a way that makes operating over them with either recursive or iterative alrogithms easy. When consuming Tokens, one can expect their type by looking at the Tag field. The data stored in the Inner field will be either a string or a \*Token depending on what Tag is. You can expect a \*Token if the Tag field is ast.LIST, and a string in all other cases. If the Tag field is ast.SYMBOL you can look it up in the VarTable or the FuncTable. The VarTable will return either a \*Token (if the symbol is a Variable) or *nil* if nothing is found. The FuncTable will return either a \*Function (if there is a match) or it will return *nil*.
|
||||
|
||||
P.S.: Ideally a token should not be re-used. You may consider them disposable. It is up to you to make sure that any Token you edit/reuse remains consistant with the type declared in its TAG. Make sure to differentiate between NUMBER and STRING with the `ast.StrIsNumber(arg string) bool` function.
|
||||
## Adding a function
|
||||
1. *Write your function in the form of an `ast.Operation`.* Any function that has the defined signature can be an Operation.
|
||||
2. *Create a `Function` to encapsulate your `Operation`.* Make sure to set the `args` and `name` fields. Args will be used to validate function calls and Name will be used in debug/log output.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue