Implement prelude.

This commit is contained in:
whitequark 2015-06-24 11:46:15 +03:00
parent 710a04cbee
commit 4d407ace4b
4 changed files with 46 additions and 13 deletions

View File

@ -1,6 +1,6 @@
"""
The :mod:`builtins` module contains the builtin Python and ARTIQ
types, such as int or float.
The :mod:`builtins` module contains the builtin Python
and ARTIQ types, such as int or float.
"""
from . import types
@ -32,16 +32,16 @@ class TList(types.TMono):
super().__init__("list", {"elt": elt})
def fn_len():
return types.TBuiltin("len")
return types.TBuiltin("function len")
def fn_round():
return types.TBuiltin("round")
return types.TBuiltin("function round")
def fn_range():
return types.TBuiltin("range")
return types.TBuiltin("function range")
def fn_syscall():
return types.TBuiltin("syscall")
return types.TBuiltin("function syscall")
# Accessors
@ -79,3 +79,8 @@ def is_collection(typ):
typ = typ.find()
return isinstance(typ, types.TTuple) or \
types.is_mono(typ, "list")
def is_function(typ, name):
typ = typ.find()
return isinstance(typ, types.TBuiltin) and \
typ.name == "function " + name

17
artiq/py2llvm/prelude.py Normal file
View File

@ -0,0 +1,17 @@
"""
The :mod:`prelude` module contains the initial global environment
in which ARTIQ kernels are evaluated.
"""
from . import builtins
def globals():
return {
"bool": builtins.TBool(),
"int": builtins.TInt(),
"float": builtins.TFloat(),
"round": builtins.fn_round(),
"len": builtins.fn_len(),
"range": builtins.fn_range(),
"syscall": builtins.fn_syscall(),
}

View File

@ -24,7 +24,7 @@ class LocalExtractor(algorithm.Visitor):
# parameters can't be declared as global or nonlocal
self.params = set()
if len(self.env_stack) == 0:
if len(self.env_stack) == 1:
self.env_stack.append(self.typing_env)
def visit_in_assign(self, node):
@ -115,7 +115,7 @@ class LocalExtractor(algorithm.Visitor):
self.global_.add(name)
self._assignable(name)
self.env_stack[0][name] = self.typing_env[name]
self.env_stack[1][name] = self.typing_env[name]
def visit_Nonlocal(self, node):
for name, loc in zip(node.names, node.name_locs):
@ -123,9 +123,9 @@ class LocalExtractor(algorithm.Visitor):
self._check_not_in(name, self.params, "a parameter", "nonlocal", loc):
continue
# nonlocal does not search global scope
# nonlocal does not search prelude and global scopes
found = False
for outer_env in reversed(self.env_stack[1:]):
for outer_env in reversed(self.env_stack[2:]):
if name in outer_env:
found = True
break
@ -156,9 +156,9 @@ class ASTTypedRewriter(algorithm.Transformer):
via :class:`LocalExtractor`.
"""
def __init__(self, engine):
def __init__(self, engine, globals={}):
self.engine = engine
self.env_stack = []
self.env_stack = [globals]
def _find_name(self, name, loc):
for typing_env in reversed(self.env_stack):
@ -990,6 +990,7 @@ class Printer(algorithm.Visitor):
def main():
import sys, fileinput, os
from . import prelude
if len(sys.argv) > 1 and sys.argv[1] == '+diag':
del sys.argv[1]
@ -1009,7 +1010,7 @@ def main():
buf = source.Buffer("".join(fileinput.input()).expandtabs(),
os.path.basename(fileinput.filename()))
parsed, comments = parse_buffer(buf, engine=engine)
typed = ASTTypedRewriter(engine=engine).visit(parsed)
typed = ASTTypedRewriter(globals=prelude.globals(), engine=engine).visit(parsed)
Inferencer(engine=engine).visit(typed)
printer = Printer(buf)

View File

@ -0,0 +1,10 @@
# RUN: %python -m artiq.py2llvm.typing %s >%t
# RUN: OutputCheck %s --file-to-check=%t
# CHECK-L: x:<built-in function len>
x = len
def f():
global len
# CHECK-L: len:int(width='a) =
len = 1