mirror of
https://github.com/Open-Argon/argon-v3.git
synced 2025-12-06 08:56:07 +00:00
parse imports with fixed paths before running all the code
This commit is contained in:
114
src/import.go
114
src/import.go
@@ -7,6 +7,7 @@ import (
|
||||
)
|
||||
|
||||
var imported = make(map[string]ArObject)
|
||||
var translatedImports = make(map[string]translatedImport)
|
||||
var importing = make(map[string]bool)
|
||||
|
||||
const modules_folder = "argon_modules"
|
||||
@@ -41,7 +42,58 @@ func readFile(path string) ([]UNPARSEcode, error) {
|
||||
return output, nil
|
||||
}
|
||||
|
||||
func importMod(realpath string, origin string, main bool, global ArObject) (ArObject, ArErr) {
|
||||
type translatedImport struct {
|
||||
translated []any
|
||||
p string
|
||||
path string
|
||||
ex string
|
||||
exc string
|
||||
origin string
|
||||
}
|
||||
|
||||
var runTranslatedImport func(translatedImport, ArObject) (ArObject, ArErr)
|
||||
|
||||
func init() {
|
||||
runTranslatedImport = __runTranslatedImport
|
||||
}
|
||||
|
||||
func __runTranslatedImport(translatedImport translatedImport, global ArObject) (ArObject, ArErr) {
|
||||
|
||||
if _, ok := imported[translatedImport.p]; ok {
|
||||
return imported[translatedImport.p], ArErr{}
|
||||
}
|
||||
|
||||
ArgsArArray := []any{}
|
||||
withoutarfile := []string{}
|
||||
if len(Args) > 1 {
|
||||
withoutarfile = Args[1:]
|
||||
}
|
||||
for _, arg := range withoutarfile {
|
||||
ArgsArArray = append(ArgsArArray, arg)
|
||||
}
|
||||
local := newscope()
|
||||
localvars := Map(anymap{
|
||||
"program": Map(anymap{
|
||||
"args": ArArray(ArgsArArray),
|
||||
"origin": ArString(translatedImport.origin),
|
||||
"cwd": ArString(translatedImport.ex),
|
||||
"exc": ArString(translatedImport.exc),
|
||||
"file": Map(anymap{
|
||||
"name": ArString(filepath.Base(translatedImport.p)),
|
||||
"path": ArString(translatedImport.p),
|
||||
}),
|
||||
"main": main,
|
||||
}),
|
||||
})
|
||||
_, runimeErr := run(translatedImport.translated, stack{global, localvars, local})
|
||||
if runimeErr.EXISTS {
|
||||
return ArObject{}, runimeErr
|
||||
}
|
||||
imported[translatedImport.p] = local
|
||||
return local, ArErr{}
|
||||
}
|
||||
|
||||
func translateImport(realpath string, origin string, main bool) (translatedImport, ArErr) {
|
||||
extention := filepath.Ext(realpath)
|
||||
path := realpath
|
||||
if extention == "" {
|
||||
@@ -49,11 +101,11 @@ func importMod(realpath string, origin string, main bool, global ArObject) (ArOb
|
||||
}
|
||||
ex, err := os.Getwd()
|
||||
if err != nil {
|
||||
return ArObject{}, ArErr{TYPE: "Import Error", message: "Could not get working directory", EXISTS: true}
|
||||
return translatedImport{}, ArErr{TYPE: "Import Error", message: "Could not get working directory", EXISTS: true}
|
||||
}
|
||||
exc, err := os.Executable()
|
||||
if err != nil {
|
||||
return ArObject{}, ArErr{TYPE: "Import Error", message: "Could not get executable", EXISTS: true}
|
||||
return translatedImport{}, ArErr{TYPE: "Import Error", message: "Could not get executable", EXISTS: true}
|
||||
}
|
||||
executable := filepath.Dir(exc)
|
||||
isABS := filepath.IsAbs(path)
|
||||
@@ -86,58 +138,26 @@ func importMod(realpath string, origin string, main bool, global ArObject) (ArOb
|
||||
}
|
||||
|
||||
if !found {
|
||||
return ArObject{}, ArErr{TYPE: "Import Error", message: "File does not exist: " + path, EXISTS: true}
|
||||
return translatedImport{}, ArErr{TYPE: "Import Error", message: "File does not exist: " + path, EXISTS: true}
|
||||
} else if importing[p] {
|
||||
return ArObject{}, ArErr{TYPE: "Import Error", message: "Circular import: " + path, EXISTS: true}
|
||||
} else if _, ok := imported[p]; ok {
|
||||
return imported[p], ArErr{}
|
||||
return translatedImport{}, ArErr{TYPE: "Import Error", message: "Circular import: " + path, EXISTS: true}
|
||||
} else if _, ok := translatedImports[p]; ok {
|
||||
return translatedImports[p], ArErr{}
|
||||
}
|
||||
importing[p] = true
|
||||
codelines, err := readFile(p)
|
||||
if err != nil {
|
||||
return ArObject{}, ArErr{TYPE: "Import Error", message: "Could not read file: " + path, EXISTS: true}
|
||||
return translatedImport{}, ArErr{TYPE: "Import Error", message: "Could not read file: " + path, EXISTS: true}
|
||||
}
|
||||
|
||||
importing[p] = true
|
||||
translated, translationerr := translate(codelines)
|
||||
importing[p] = false
|
||||
|
||||
if translationerr.EXISTS {
|
||||
return ArObject{}, translationerr
|
||||
return translatedImport{}, translationerr
|
||||
}
|
||||
ArgsArArray := []any{}
|
||||
withoutarfile := []string{}
|
||||
if len(Args) > 1 {
|
||||
withoutarfile = Args[1:]
|
||||
}
|
||||
for _, arg := range withoutarfile {
|
||||
ArgsArArray = append(ArgsArArray, arg)
|
||||
}
|
||||
local := newscope()
|
||||
localvars := Map(anymap{
|
||||
"program": Map(anymap{
|
||||
"args": ArArray(ArgsArArray),
|
||||
"origin": ArString(origin),
|
||||
"import": builtinFunc{"import", func(args ...any) (any, ArErr) {
|
||||
if len(args) != 1 {
|
||||
return nil, ArErr{"Import Error", "Invalid number of arguments", 0, realpath, "", true}
|
||||
}
|
||||
if _, ok := args[0].(string); !ok {
|
||||
return nil, ArErr{"Import Error", "Invalid argument type", 0, realpath, "", true}
|
||||
}
|
||||
return importMod(args[0].(string), filepath.Dir(filepath.ToSlash(p)), false, global)
|
||||
}},
|
||||
"cwd": ArString(ex),
|
||||
"exc": ArString(exc),
|
||||
"file": Map(anymap{
|
||||
"name": ArString(filepath.Base(p)),
|
||||
"path": ArString(p),
|
||||
}),
|
||||
"main": main,
|
||||
}),
|
||||
})
|
||||
_, runimeErr := run(translated, stack{global, localvars, local})
|
||||
importing[p] = false
|
||||
if runimeErr.EXISTS {
|
||||
return ArObject{}, runimeErr
|
||||
}
|
||||
imported[p] = local
|
||||
return local, ArErr{}
|
||||
|
||||
translatedImports[p] = translatedImport{translated, p, path, ex, exc, origin}
|
||||
return translatedImports[p], ArErr{}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user