Skip to content

Commit

Permalink
[ysh refactor] Move 'use' builtin under 'source'
Browse files Browse the repository at this point in the history
They will share much of the same logic, like tracing, and ///osh and
///ysh as embedded data.
  • Loading branch information
Andy C committed Sep 29, 2024
1 parent 20feae8 commit 8613ec3
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 82 deletions.
90 changes: 89 additions & 1 deletion builtin/meta_oils.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,12 @@ def Run(self, cmd_val):
cmd_flags=cmd_eval.RaiseControlFlow)


class Source(vm._Builtin):
class ShellFile(vm._Builtin):
"""
These share code:
- 'source' builtin for OSH
- 'use' builtin for YSH
"""

def __init__(
self,
Expand All @@ -106,6 +111,7 @@ def __init__(
tracer, # type: dev.Tracer
errfmt, # type: ui.ErrorFormatter
loader, # type: pyutil._ResourceLoader
ysh_use=False, # type: bool
):
# type: (...) -> None
self.parse_ctx = parse_ctx
Expand All @@ -116,10 +122,92 @@ def __init__(
self.tracer = tracer
self.errfmt = errfmt
self.loader = loader
self.ysh_use = ysh_use

self.mem = cmd_ev.mem

def Run(self, cmd_val):
# type: (cmd_value.Argv) -> int
"""
Use is like Source
"""
if self.ysh_use:
return self._Use(cmd_val)
else:
return self._Source(cmd_val)

def _Use(self, cmd_val):
# type: (cmd_value.Argv) -> int
"""
Module system with all the power of Python, but still a proc
use util.ysh # util is a value.Obj
# Importing a bunch of words
use dialect-ninja.ysh { all } # requires 'provide' in dialect-ninja
use dialect-github.ysh { all }
# This declares some names
use --extern grep sed
# Renaming
use util.ysh (&myutil)
# Ignore
use util.ysh (&_)
# Picking specifics
use util.ysh {
pick log die
pick foo (&myfoo)
}
# A long way to write this is:
use util.ysh
const log = util.log
const die = util.die
const myfoo = util.foo
Another way is:
for name in log die {
call setVar(name, util[name])
# value.Obj may not support [] though
# get(propView(util), name, null) is a long way of writing it
}
Other considerations:
- Statically parseable subset? For fine-grained static tree-shaking
- We're doing coarse dynamic tree-shaking first though
- if TYPE_CHECKING is an issue
- that can create circular dependencies, especially with gradual typing,
when you go dynamic to static (like Oils did)
- I guess you can have
- use --static parse_lib.ysh { pick ParseContext }
"""
_, arg_r = flag_util.ParseCmdVal('use', cmd_val)

mod_path, _ = arg_r.ReadRequired2('requires a module path')

log('m %s', mod_path)

arg_r.Done()

# TODO on usage:
# - typed arg is value.Place
# - block arg binds 'pick' and 'all'

# TODO:
# with ctx_Module
# and then do something very similar to 'source'

return 0
return 0

def _Source(self, cmd_val):
# type: (cmd_value.Argv) -> int
attrs, arg_r = flag_util.ParseCmdVal('source', cmd_val)
arg = arg_types.source(attrs.attrs)
Expand Down
78 changes: 0 additions & 78 deletions builtin/module_ysh.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,81 +54,3 @@ def Run(self, cmd_val):
return 1
self.guards[name] = True
return 0


class Use(vm._Builtin):
"""
Module system with all the power of Python, but still a proc
use util.ysh # util is a value.Obj
# Importing a bunch of words
use dialect-ninja.ysh { all } # requires 'provide' in dialect-ninja
use dialect-github.ysh { all }
# This declares some names
use --extern grep sed
# Renaming
use util.ysh (&myutil)
# Ignore
use util.ysh (&_)
# Picking specifics
use util.ysh {
pick log die
pick foo (&myfoo)
}
# A long way to write this is:
use util.ysh
const log = util.log
const die = util.die
const myfoo = util.foo
Another way is:
for name in log die {
call setVar(name, util[name])
# value.Obj may not support [] though
# get(propView(util), name, null) is a long way of writing it
}
Other considerations:
- Statically parseable subset? For fine-grained static tree-shaking
- We're doing coarse dynamic tree-shaking first though
- if TYPE_CHECKING is an issue
- that can create circular dependencies, especially with gradual typing,
when you go dynamic to static (like Oils did)
- I guess you can have
- use --static parse_lib.ysh { pick ParseContext }
"""

def __init__(self, mem, errfmt):
# type: (state.Mem, ui.ErrorFormatter) -> None
self.mem = mem
self.errfmt = errfmt

def Run(self, cmd_val):
# type: (cmd_value.Argv) -> int
_, arg_r = flag_util.ParseCmdVal('use', cmd_val)

mod_path, _ = arg_r.ReadRequired2('requires a module path')

log('m %s', mod_path)

arg_r.Done()

# TODO on usage:
# - typed arg is value.Place
# - block arg binds 'pick' and 'all'

# TODO:
# with ctx_Module
# and then do something very similar to 'source'

return 0
13 changes: 10 additions & 3 deletions core/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -632,8 +632,16 @@ def Main(
b[builtin_i.extern_] = meta_oils.Extern(shell_ex, procs, errfmt)

# Meta builtins
source_builtin = meta_oils.Source(parse_ctx, search_path, cmd_ev, fd_state,
tracer, errfmt, loader)
b[builtin_i.use] = meta_oils.ShellFile(parse_ctx,
search_path,
cmd_ev,
fd_state,
tracer,
errfmt,
loader,
ysh_use=True)
source_builtin = meta_oils.ShellFile(parse_ctx, search_path, cmd_ev,
fd_state, tracer, errfmt, loader)
b[builtin_i.source] = source_builtin
b[builtin_i.dot] = source_builtin
b[builtin_i.eval] = meta_oils.Eval(parse_ctx, exec_opts, cmd_ev, tracer,
Expand All @@ -644,7 +652,6 @@ def Main(
b[builtin_i.source_guard] = module_ysh.SourceGuard(guards, exec_opts,
errfmt)
b[builtin_i.is_main] = module_ysh.IsMain(mem)
b[builtin_i.use] = module_ysh.Use(mem, errfmt)

# Errors
b[builtin_i.error] = error_ysh.Error()
Expand Down

0 comments on commit 8613ec3

Please sign in to comment.