Making headway towards a runnable state
This commit is contained in:
parent
8dd071625f
commit
4243a9355c
6 changed files with 80 additions and 32 deletions
|
@ -1,5 +1,6 @@
|
||||||
py_project(
|
py_project(
|
||||||
name = "lib",
|
name = "lilith",
|
||||||
|
main = "src/python/lilith/__main__.py",
|
||||||
lib_deps = [
|
lib_deps = [
|
||||||
py_requirement("lark"),
|
py_requirement("lark"),
|
||||||
py_requirement("pyyaml"),
|
py_requirement("pyyaml"),
|
||||||
|
@ -9,16 +10,3 @@ py_project(
|
||||||
py_requirement("hypothesis"),
|
py_requirement("hypothesis"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
zapp_binary(
|
|
||||||
name = "lilith",
|
|
||||||
main = "src/python/lilith/__main__.py",
|
|
||||||
deps = [
|
|
||||||
":lib",
|
|
||||||
# FIXME: Due to zapp bug(s), replicating requirements here.
|
|
||||||
py_requirement("lark"),
|
|
||||||
py_requirement("pyyaml"),
|
|
||||||
py_requirement("markdown"),
|
|
||||||
py_requirement("prompt_toolkit"),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ FIXME: We need the object language
|
||||||
|
|
||||||
!def[openapi, yaml[]]
|
!def[openapi, yaml[]]
|
||||||
|
|
||||||
!def[main, lilith[]]
|
!def[main, lang[lilith]]
|
||||||
; is importing a bang-operation?
|
; is importing a bang-operation?
|
||||||
|
|
||||||
print[str.join["", [pitch, syntax]]]
|
print[str.join["", [pitch, syntax]]]
|
||||||
|
|
|
@ -75,21 +75,23 @@ def batch(opts, args, runtime):
|
||||||
main = Symbol(main)
|
main = Symbol(main)
|
||||||
|
|
||||||
# Register
|
# Register
|
||||||
runtime.modules[mod.name] = mod
|
runtime.modules.update({mod.name: mod})
|
||||||
|
|
||||||
print("DEBUG: batch mode")
|
print("DEBUG: batch mode")
|
||||||
print(
|
print(
|
||||||
yaml.dump(
|
yaml.dump(
|
||||||
{
|
{
|
||||||
"type": "runtime",
|
"type": "runtime",
|
||||||
"name": runtime.name,
|
"name": runtime.name.name,
|
||||||
"modules": {
|
"modules": {
|
||||||
m.name: {
|
m.name.name: {
|
||||||
"defs": {dname.name: repr(d) for dname, d in m.defs.items()}
|
"defs": {dname.name: repr(d) for dname, d in m.defs.items()}
|
||||||
}
|
}
|
||||||
for m in runtime.modules.values()
|
for m in runtime.modules.values()
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
|
default_flow_style=False,
|
||||||
|
sort_keys=False,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -125,11 +127,27 @@ if __name__ == "__main__":
|
||||||
sys.path.insert(0, _e)
|
sys.path.insert(0, _e)
|
||||||
|
|
||||||
# Building up a bootstrap interface for going out to many Python features.
|
# Building up a bootstrap interface for going out to many Python features.
|
||||||
runtime = Runtime("__runtime__", Symbol(opts.prelude), {})
|
runtime = Runtime(Symbol("__runtime__"), Symbol(opts.prelude), {})
|
||||||
|
|
||||||
|
def _lil(runtime=None,
|
||||||
|
module=None,
|
||||||
|
body=None,
|
||||||
|
name=None):
|
||||||
|
"""The implementation of the Lilith lang as an eval type."""
|
||||||
|
expr = parse_expr(body)
|
||||||
|
return eval(runtime, module, Bindings(), expr)
|
||||||
|
|
||||||
bootstrap = Module(
|
bootstrap = Module(
|
||||||
"lilith.bootstrap",
|
Symbol("lilith.bootstrap"),
|
||||||
[],
|
[],
|
||||||
{Symbol("py"): lambda *args, body=None, **kwargs: eval(body)},
|
{
|
||||||
|
# The foundational meaning of lang[]
|
||||||
|
Symbol("lang"): lambda evaluator, body=None: evaluator(body),
|
||||||
|
# The Python FFI escape hatch
|
||||||
|
Symbol("py"): lambda *args, body=None, **kwargs: eval(body),
|
||||||
|
# The Lilith self-interpreter
|
||||||
|
Symbol("lilith"): _lil,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
runtime.modules[Symbol(bootstrap.name)] = bootstrap
|
runtime.modules[Symbol(bootstrap.name)] = bootstrap
|
||||||
prelude_mod = read_buffer(
|
prelude_mod = read_buffer(
|
||||||
|
|
|
@ -10,10 +10,9 @@ STRING: /""".*?"""/ | /".*?"/
|
||||||
int: INT
|
int: INT
|
||||||
float: FLOAT
|
float: FLOAT
|
||||||
number: int | float
|
number: int | float
|
||||||
word: "nil" -> nil
|
|
||||||
| "true" -> true
|
word: WORD ("." WORD)* -> word
|
||||||
| "false" -> false
|
|
||||||
| WORD ("." WORD)* -> word
|
|
||||||
string: STRING
|
string: STRING
|
||||||
|
|
||||||
list: "[" (expr ("," expr)*)? "]"
|
list: "[" (expr ("," expr)*)? "]"
|
||||||
|
@ -21,7 +20,14 @@ list: "[" (expr ("," expr)*)? "]"
|
||||||
pair: expr ":" expr
|
pair: expr ":" expr
|
||||||
dict: "{" (pair ("," pair)*)? "}"
|
dict: "{" (pair ("," pair)*)? "}"
|
||||||
|
|
||||||
atom: number | word | string | list | dict
|
atom: number
|
||||||
|
| word
|
||||||
|
| string
|
||||||
|
| list
|
||||||
|
| dict
|
||||||
|
| "nil" -> nil
|
||||||
|
| "true" -> true
|
||||||
|
| "false" -> false
|
||||||
|
|
||||||
application: word "[" arguments? "]"
|
application: word "[" arguments? "]"
|
||||||
|
|
||||||
|
|
|
@ -72,9 +72,7 @@ def eval(ctx: Runtime, mod: Module, locals: Bindings, expr):
|
||||||
return lookup(ctx, mod, locals, expr)
|
return lookup(ctx, mod, locals, expr)
|
||||||
|
|
||||||
elif isinstance(expr, Apply):
|
elif isinstance(expr, Apply):
|
||||||
# FIXME (arrdem 2021-08-21):
|
# Evaluate the call target
|
||||||
# Apply should be (apply <expr> <args> <kwargs>).
|
|
||||||
# Now no distinction is made between strings ("") and symbols/barewords
|
|
||||||
fun = eval(ctx, mod, locals, expr.target)
|
fun = eval(ctx, mod, locals, expr.target)
|
||||||
# Evaluate the parameters
|
# Evaluate the parameters
|
||||||
args = eval(ctx, mod, locals, expr.args.positionals)
|
args = eval(ctx, mod, locals, expr.args.positionals)
|
||||||
|
|
|
@ -8,6 +8,10 @@ load("@rules_python//python:defs.bzl",
|
||||||
_py_library = "py_library",
|
_py_library = "py_library",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
load("@rules_zapp//zapp:zapp.bzl",
|
||||||
|
"zapp_binary",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def py_requirement(*args, **kwargs):
|
def py_requirement(*args, **kwargs):
|
||||||
"""A re-export of requirement()"""
|
"""A re-export of requirement()"""
|
||||||
|
@ -146,6 +150,7 @@ py_resources = rule(
|
||||||
)
|
)
|
||||||
|
|
||||||
def py_project(name=None,
|
def py_project(name=None,
|
||||||
|
main=None,
|
||||||
lib_srcs=None,
|
lib_srcs=None,
|
||||||
lib_deps=None,
|
lib_deps=None,
|
||||||
lib_data=None,
|
lib_data=None,
|
||||||
|
@ -184,8 +189,10 @@ def py_project(name=None,
|
||||||
"**/*.pyc",
|
"**/*.pyc",
|
||||||
])
|
])
|
||||||
|
|
||||||
|
lib_name = name if not main else "lib"
|
||||||
|
|
||||||
py_library(
|
py_library(
|
||||||
name=name,
|
name=lib_name,
|
||||||
srcs=lib_srcs,
|
srcs=lib_srcs,
|
||||||
deps=lib_deps,
|
deps=lib_deps,
|
||||||
data=lib_data,
|
data=lib_data,
|
||||||
|
@ -198,12 +205,43 @@ def py_project(name=None,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if main:
|
||||||
|
py_binary(
|
||||||
|
name=name,
|
||||||
|
main=main,
|
||||||
|
srcs=lib_srcs,
|
||||||
|
deps=lib_deps,
|
||||||
|
data=lib_data,
|
||||||
|
imports=[
|
||||||
|
"src/python",
|
||||||
|
"src/resources",
|
||||||
|
],
|
||||||
|
visibility = [
|
||||||
|
"//visibility:public",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
zapp_binary(
|
||||||
|
name=name + ".zapp",
|
||||||
|
main=main,
|
||||||
|
srcs=lib_srcs,
|
||||||
|
deps=lib_deps,
|
||||||
|
data=lib_data,
|
||||||
|
imports=[
|
||||||
|
"src/python",
|
||||||
|
"src/resources",
|
||||||
|
],
|
||||||
|
visibility = [
|
||||||
|
"//visibility:public",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
for src in test_srcs:
|
for src in test_srcs:
|
||||||
if "test_" in src:
|
if "test_" in src:
|
||||||
py_pytest(
|
py_pytest(
|
||||||
name=src.split("/")[-1],
|
name=src.split("/")[-1],
|
||||||
srcs=[src] + [f for f in test_srcs if "test_" not in f],
|
srcs=[src] + [f for f in test_srcs if "test_" not in f],
|
||||||
deps=[name] + (test_deps or []),
|
deps=[lib_name] + (test_deps or []),
|
||||||
data=test_data,
|
data=test_data,
|
||||||
imports=[
|
imports=[
|
||||||
"test/python",
|
"test/python",
|
||||||
|
|
Loading…
Reference in a new issue