Making headway towards a runnable state

This commit is contained in:
Reid 'arrdem' McKenzie 2021-08-21 20:02:54 -06:00
parent d02f53dc52
commit 4a5262c95c
6 changed files with 80 additions and 32 deletions

View file

@ -1,5 +1,6 @@
py_project(
name = "lib",
name = "lilith",
main = "src/python/lilith/__main__.py",
lib_deps = [
py_requirement("lark"),
py_requirement("pyyaml"),
@ -9,16 +10,3 @@ py_project(
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"),
],
)

View file

@ -36,7 +36,7 @@ FIXME: We need the object language
!def[openapi, yaml[]]
!def[main, lilith[]]
!def[main, lang[lilith]]
; is importing a bang-operation?
print[str.join["", [pitch, syntax]]]

View file

@ -75,21 +75,23 @@ def batch(opts, args, runtime):
main = Symbol(main)
# Register
runtime.modules[mod.name] = mod
runtime.modules.update({mod.name: mod})
print("DEBUG: batch mode")
print(
yaml.dump(
{
"type": "runtime",
"name": runtime.name,
"name": runtime.name.name,
"modules": {
m.name: {
m.name.name: {
"defs": {dname.name: repr(d) for dname, d in m.defs.items()}
}
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)
# 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(
"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
prelude_mod = read_buffer(

View file

@ -10,10 +10,9 @@ STRING: /""".*?"""/ | /".*?"/
int: INT
float: FLOAT
number: int | float
word: "nil" -> nil
| "true" -> true
| "false" -> false
| WORD ("." WORD)* -> word
word: WORD ("." WORD)* -> word
string: STRING
list: "[" (expr ("," expr)*)? "]"
@ -21,7 +20,14 @@ list: "[" (expr ("," expr)*)? "]"
pair: expr ":" expr
dict: "{" (pair ("," pair)*)? "}"
atom: number | word | string | list | dict
atom: number
| word
| string
| list
| dict
| "nil" -> nil
| "true" -> true
| "false" -> false
application: word "[" arguments? "]"

View file

@ -72,9 +72,7 @@ def eval(ctx: Runtime, mod: Module, locals: Bindings, expr):
return lookup(ctx, mod, locals, expr)
elif isinstance(expr, Apply):
# FIXME (arrdem 2021-08-21):
# Apply should be (apply <expr> <args> <kwargs>).
# Now no distinction is made between strings ("") and symbols/barewords
# Evaluate the call target
fun = eval(ctx, mod, locals, expr.target)
# Evaluate the parameters
args = eval(ctx, mod, locals, expr.args.positionals)

View file

@ -8,6 +8,10 @@ load("@rules_python//python:defs.bzl",
_py_library = "py_library",
)
load("@rules_zapp//zapp:zapp.bzl",
"zapp_binary",
)
def py_requirement(*args, **kwargs):
"""A re-export of requirement()"""
@ -146,6 +150,7 @@ py_resources = rule(
)
def py_project(name=None,
main=None,
lib_srcs=None,
lib_deps=None,
lib_data=None,
@ -184,8 +189,10 @@ def py_project(name=None,
"**/*.pyc",
])
lib_name = name if not main else "lib"
py_library(
name=name,
name=lib_name,
srcs=lib_srcs,
deps=lib_deps,
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:
if "test_" in src:
py_pytest(
name=src.split("/")[-1],
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,
imports=[
"test/python",