negative number parsing

This commit is contained in:
Aidan 2020-08-21 00:14:31 -07:00
parent 69536783c7
commit 90284f2d06
No known key found for this signature in database
GPG key ID: 327711E983899316
3 changed files with 86 additions and 0 deletions

View file

@ -215,6 +215,11 @@ error:
func StrIsNumber(arg string) bool { func StrIsNumber(arg string) bool {
dotCount := 0 dotCount := 0
// negative nums
if len(arg) > 0 && arg[0] == '-' {
arg = arg[1:]
}
for _, char := range arg { for _, char := range arg {
if !unicode.IsDigit(char) { if !unicode.IsDigit(char) {
if char == '.' && dotCount == 0 { if char == '.' && dotCount == 0 {

View file

@ -157,6 +157,13 @@ func GenFuncTable() ast.FuncTable {
Args: 2, Args: 2,
}, },
"substr": &ast.Function{
Function: Substr,
Name: "substr",
TimesCalled: 0,
Args: 3,
},
"exit": &ast.Function{ "exit": &ast.Function{
Function: ExitShell, Function: ExitShell,
Name: "exit", Name: "exit",

View file

@ -145,6 +145,80 @@ func Join(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token {
return ret return ret
} }
/* takes three arguments:
* 1. start index
* 2. end index
* 3. source
* Returns a substring from source delimited by args 1 and 2.
* First two args must be integers (4 or 4.0 but not 4.3)
*
* Example: (substr 1 5 "Linus Torvalds") -> "inus "
*/
func Substr(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token {
start := in.Eval(ft, vt, false)
if start == nil || start.Next == nil || start.Next.Next == nil {
log.Log(log.ERR,
"an argument evaluated to nil",
"substr")
return nil
}
end := start.Next
str := end.Next
if start.Tag != ast.NUMBER || end.Tag != ast.NUMBER || str.Tag != ast.STRING {
log.Log(log.ERR,
"incorrect types of args",
"substr")
return nil
}
ed_idx := 0
st_idx, err := strconv.Atoi(start.Value())
ed_idx, err = strconv.Atoi(end.Value())
if err != nil {
log.Log(log.ERR,
"error parsing args: " + err.Error(),
"substr")
return nil
}
strlen := len(str.Value())
if st_idx < 0 {
st_idx += strlen
}
if ed_idx < 0 {
ed_idx += strlen
}
if st_idx < 0 || st_idx >= strlen {
log.Log(log.ERR,
"first index out of bounds",
"substr")
return nil
}
if ed_idx < 0 || ed_idx >= strlen {
log.Log(log.ERR,
"last index out of bounds",
"substr")
return nil
}
if st_idx > ed_idx {
log.Log(log.ERR,
"start must be less than end",
"substr")
return nil
}
res := str.Value()[st_idx:ed_idx]
ret := &ast.Token{Tag: ast.STRING}
ret.Set(res)
return ret
}
/* Takes one arg, returns nil /* Takes one arg, returns nil
* Prints a string to stdout * Prints a string to stdout
* Unquotes string so user can add escaped chars like \n, \t, etc * Unquotes string so user can add escaped chars like \n, \t, etc