Finishes import functionality, improves completion to react to new procs getting added (but not vars), further error message improvements

This commit is contained in:
sloum 2023-06-13 14:01:32 -07:00
parent 93a4ebb4b8
commit ccfc3537fe
6 changed files with 65 additions and 84 deletions

View File

@ -46,5 +46,4 @@ var (
// This is the main stack for the language
globalStack stack = NewStack()
globalRetStack stack = NewStack()
imports = make(map[string]bool)
)

View File

@ -33,6 +33,7 @@ ReplacedSymbol:
}
case PROC:
en.Add(t.val.(proc).name, t)
completions = append(completions, t.val.(proc).name)
case IF:
v, err := globalStack.Pop()
if err != nil {
@ -112,7 +113,7 @@ ReplacedSymbol:
case SYMBOL:
foundIn, err := en.Find(t.val.(string))
if err != nil {
return err
return fmt.Errorf("%s (Line %d of %s)", err.Error(), t.line, t.file)
}
x := foundIn.vars[t.val.(string)]

View File

@ -1281,11 +1281,6 @@ func libImport(line int, fp string, en *env) error {
if t.kind != STRING {
return fmt.Errorf("`import` expects a STRING on TOS, not %s", kindToString(t.kind))
}
// Use 'imports' var (found in globals.go) to mark once imported
// XXX scratch that. Add a map to the env struct and mark them there
// so that they can get imported wherever in scope, but never doubly
// so? A way to search parent scopes for the value will be important
// as well
if en.Imported(t.val.(string)) {
return nil
}
@ -1308,12 +1303,6 @@ func libImport(line int, fp string, en *env) error {
return err
}
en.imports[t.val.(string)] = true
case "io":
err = lexParseInterpret(ioImport, en, "io")
if err != nil {
return err
}
en.imports[t.val.(string)] = true
default:
p := ExpandedAbsFilepath(t.val.(string))
s, err := readFile(p)

View File

@ -1,28 +0,0 @@
STRING var! stdout
"/dev/fd/1" set! stdout
STRING var! stderr
"/dev/fd/2" set! stderr
STRING var! stdin
"/dev/fd/0" set! stdin
STRING var! devnull
"/dev/null" set! devnull
proc print
| Stack: ANY
Read :
Push :
Notes: Prints the value on TOS |
STRING cast stdout file-write
.
proc println
| Stack: ANY
Read :
Push :
Notes: Prints the value on TOS + a newline |
STRING cast "\n" append stdout file-write
.

View File

@ -1,3 +1,37 @@
# std contains misc useful procedures and variables
# that make working in felise easier, but are coded
# in felise itself, rather than as built-in procs
# writen in go
STRING var! stdout
"/dev/fd/1" set! stdout
STRING var! stderr
"/dev/fd/2" set! stderr
STRING var! stdin
"/dev/fd/0" set! stdin
STRING var! devnull
"/dev/null" set! devnull
proc print
| Stack: ANY
Read :
Push :
Notes: Prints the value on TOS |
STRING cast stdout file-write
.
proc println
| Stack: ANY
Read :
Push :
Notes: Prints the value on TOS + a newline |
STRING cast "\n" append stdout file-write
.
proc! ++!
| Stack:
Read : SYMBOL(INT)

72
main.go
View File

@ -1,4 +1,8 @@
/*
_
|, _ |. __ _
| (/,||_) (/,
Copyright (C) 2023 Brian Evans (aka sloum). All rights reserved.
This source code is available under the terms of the ffsl, or,
@ -23,9 +27,8 @@ import (
)
const (
version float64 = 0.1
nameo string = "felise"
logo string = ` _
version float64 = 0.2
logo string = ` _
|, _ |. __ _
| (/,||_) (/,`
)
@ -35,13 +38,13 @@ var initialTerm ln.ModeApplier = nil
var linerTerm ln.ModeApplier = nil
var flagArgs []string
var completions = []string{
"var!", "set!", "scoped-var!", "scoped-set!", "proc", "proc!", "length", "return",
"print", "println", "dup", "drop", "over", "swap", "cast", "type", "while",
"var!", "set!", "scoped-var!", "scoped-set!", "proc", "proc!", "length",
"dup", "drop", "over", "swap", "cast", "type", "while", "return",
"dowhile", "if", "else", "and", "or", "stackdump", "clearstack",
"->", "<-", "=>", "->!", "=>!", "append", "append!", "list-get", "list-set",
"list-set!", "split", "join", "file-write", "file-remove", "file-exists?",
"file-read", "docstring!", "input", "re-match?", "re-find", "re-replace", "slice",
"stackdepth", "exit", "stdin", "stdout", "stderr", "devnull", "net-get",
"->", "<-", "=>", "->!", "=>!", "append", "append!", "list-get",
"list-set", "list-set!", "split", "join", "file-write", "file-remove",
"file-exists?", "file-read", "docstring!", "input", "re-match?",
"re-find", "re-replace", "slice", "stackdepth", "net-get",
}
//go:embed lib/std.fe
@ -50,40 +53,9 @@ var stdImport string
//go:embed lib/math.fe
var mathImport string
//go:embed lib/io.fe
var ioImport string
//go:embed lib/stack.fe
var stackImport string
/*
_
|, _ |. __ _
| (/,||_) (/,
TODO / Ideas / Etc.
del [varname/procname]
Will remove the symbol and value from the symbol table,
not sure if this is useful but it feels like it adds
completeness
---
Builtins on radar:
- `%`, `not`
Need some way to respond to args given at runtime... may need
an array for that. Or maybe not? Maybe an `arg` word can be
defined so that: `0 INT flag myarg` would let someone pass an
arg: `felise myfile.fe --myarg=24`, with the arg defaulting to
0... does something like that work?
*/
func prompt(l *ln.State, cont bool) string {
p := "> "
@ -102,6 +74,15 @@ func VersionString() string {
return fmt.Sprintf("%.2f\n", version)
}
func loadStdLib(en *env) error {
err := lexParseInterpret(stdImport, en, "std")
if err != nil {
return err
}
en.imports["std"] = true
return nil
}
func repl() {
fmt.Printf("%s\nfelise version %s(c) 2023 sloum, all rights reserved\nLicensed under the terms of the Floodgap Free Software License\n(`bye` or `exit` to quit)\n\n", logo,VersionString())
initialTerm, _ = ln.TerminalMode()
@ -128,6 +109,10 @@ func repl() {
var text strings.Builder
var cont bool
baseEnv := NewEnv(nil)
err := loadStdLib(baseEnv)
if err != nil {
processInterpretError(err, "std")
}
for {
if linerTerm != nil {
@ -169,8 +154,6 @@ func lexParseInterpret(s string, en *env, file string) error {
}
return err
}
// TODO just separated lex and process err
// Make sure all is working
func processInterpretError(err error, file string) {
if err != nil {
@ -185,7 +168,6 @@ func processInterpretError(err error, file string) {
}
}
// TODO add file input
func main() {
verFlag := flag.Bool("v", false, "Print version information and exit")
flag.BoolVar(&debug, "debug", false, "Turns on debug mode")
@ -202,6 +184,10 @@ func main() {
os.Exit(1)
}
en := NewEnv(nil)
err = loadStdLib(en)
if err != nil {
processInterpretError(err, "std")
}
if len(flagArgs) > 1 {
t := make([]token, len(flagArgs)-1)
for i, s := range flagArgs[1:] {