1.1 --- a/common.py Fri Nov 11 00:03:05 2016 +0100
1.2 +++ b/common.py Fri Nov 11 00:05:34 2016 +0100
1.3 @@ -510,6 +510,26 @@
1.4 )
1.5 return self.process_structure_node(invocation)
1.6
1.7 + def process_print_node(self, n):
1.8 +
1.9 + """
1.10 + Process the given print node 'n' as an invocation on a stream of the
1.11 + form...
1.12 +
1.13 + $print(dest, args, nl)
1.14 +
1.15 + The special function name will be translated elsewhere.
1.16 + """
1.17 +
1.18 + nl = isinstance(n, compiler.ast.Printnl)
1.19 + invocation = compiler.ast.CallFunc(
1.20 + compiler.ast.Name("$print"),
1.21 + [n.dest or compiler.ast.Name("None"),
1.22 + compiler.ast.List(list(n.nodes)),
1.23 + nl and compiler.ast.Name("True") or compiler.ast.Name("false")]
1.24 + )
1.25 + return self.process_structure_node(invocation)
1.26 +
1.27 def process_slice_node(self, n, expr=None):
1.28
1.29 """
2.1 --- a/inspector.py Fri Nov 11 00:03:05 2016 +0100
2.2 +++ b/inspector.py Fri Nov 11 00:05:34 2016 +0100
2.3 @@ -278,6 +278,11 @@
2.4 self.process_structure(n)
2.5 self.trackers[-1].abandon_returning_branch()
2.6
2.7 + # Print statements.
2.8 +
2.9 + elif isinstance(n, (compiler.ast.Print, compiler.ast.Printnl)):
2.10 + self.process_print_node(n)
2.11 +
2.12 # Invocations.
2.13
2.14 elif isinstance(n, compiler.ast.CallFunc):
2.15 @@ -774,7 +779,7 @@
2.16
2.17 path = self.get_namespace_path()
2.18
2.19 - # Special names.
2.20 + # Special names that have already been identified.
2.21
2.22 if n.name.startswith("$"):
2.23 value = self.get_special(n.name)
2.24 @@ -801,6 +806,20 @@
2.25 self.set_special(n.name, value)
2.26 return value
2.27
2.28 + # Special case for print operations.
2.29 +
2.30 + elif n.name.startswith("$print"):
2.31 +
2.32 + # Attempt to get a reference.
2.33 +
2.34 + ref = self.get_builtin("print_")
2.35 +
2.36 + # Record the imported name and provide the resolved name reference.
2.37 +
2.38 + value = ResolvedNameRef(n.name, ref)
2.39 + self.set_special(n.name, value)
2.40 + return value
2.41 +
2.42 # Test for self usage, which is only allowed in methods.
2.43
2.44 if n.name == "self" and not (self.in_function and self.in_class):
3.1 --- a/lib/__builtins__/__init__.py Fri Nov 11 00:03:05 2016 +0100
3.2 +++ b/lib/__builtins__/__init__.py Fri Nov 11 00:05:34 2016 +0100
3.3 @@ -96,7 +96,7 @@
3.4 from __builtins__.character import chr, hex, oct, ord, unichr
3.5 from __builtins__.comparable import cmp, hash
3.6 from __builtins__.identity import callable, help, id, isinstance, issubclass, repr
3.7 -from __builtins__.io import eval, open, raw_input
3.8 +from __builtins__.io import open, raw_input, print_, sysfile
3.9 from __builtins__.iterable import all, any, enumerate, filter, iter, len, map, max, min, range, reduce, reversed, sorted, sum, zip
3.10 from __builtins__.namespace import dir, globals, locals, vars
3.11 from __builtins__.numeric import abs, divmod, pow, round
4.1 --- a/lib/__builtins__/file.py Fri Nov 11 00:03:05 2016 +0100
4.2 +++ b/lib/__builtins__/file.py Fri Nov 11 00:05:34 2016 +0100
4.3 @@ -3,7 +3,7 @@
4.4 """
4.5 File objects.
4.6
4.7 -Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
4.8 +Copyright (C) 2015, 2016 Paul Boddie <paul@boddie.org.uk>
4.9
4.10 This program is free software; you can redistribute it and/or modify it under
4.11 the terms of the GNU General Public License as published by the Free Software
4.12 @@ -20,6 +20,10 @@
4.13 """
4.14
4.15 class file(object):
4.16 +
4.17 + "A file abstraction."
4.18 +
4.19 + def __init__(self, name, mode=None, buffering=None): pass
4.20 def read(self, n=None): pass
4.21 def write(self, s): pass
4.22 def close(self): pass
5.1 --- a/lib/__builtins__/io.py Fri Nov 11 00:03:05 2016 +0100
5.2 +++ b/lib/__builtins__/io.py Fri Nov 11 00:05:34 2016 +0100
5.3 @@ -3,7 +3,7 @@
5.4 """
5.5 Input/output-related functions.
5.6
5.7 -Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
5.8 +Copyright (C) 2015, 2016 Paul Boddie <paul@boddie.org.uk>
5.9
5.10 This program is free software; you can redistribute it and/or modify it under
5.11 the terms of the GNU General Public License as published by the Free Software
5.12 @@ -19,8 +19,69 @@
5.13 this program. If not, see <http://www.gnu.org/licenses/>.
5.14 """
5.15
5.16 -def eval(source, globals=None, locals=None): pass
5.17 -def open(name, mode=None, buffering=None): pass
5.18 +from native import _read, _write
5.19 +from sys import stdout
5.20 +
5.21 +class sysfile:
5.22 +
5.23 + "A system-level file object."
5.24 +
5.25 + def __init__(self, fd):
5.26 +
5.27 + "Initialise the file with the given 'fd'."
5.28 +
5.29 + self.fd = fd
5.30 +
5.31 + def read(self, n):
5.32 +
5.33 + "Read 'n' bytes from the file."
5.34 +
5.35 + return _read(self.fd, n)
5.36 +
5.37 + def write(self, s):
5.38 +
5.39 + "Write 's' to the file."
5.40 +
5.41 + _write(self.fd, str(s))
5.42 +
5.43 +def open(name, mode=None, buffering=None):
5.44 +
5.45 + """
5.46 + Open the file with the given 'name', using the given 'mode' and applying the
5.47 + indicated 'buffering'.
5.48 + """
5.49 +
5.50 + return file(name, mode, buffering)
5.51 +
5.52 def raw_input(prompt=None): pass
5.53
5.54 +def print_(dest, args, nl):
5.55 +
5.56 + """
5.57 + Write to 'dest' the string representation of 'args', adding a newline if
5.58 + 'nl' is given as a true value.
5.59 + """
5.60 +
5.61 + # Write to standard output if dest is not specified.
5.62 +
5.63 + dest = dest or stdout
5.64 +
5.65 + first = True
5.66 +
5.67 + for arg in args:
5.68 +
5.69 + # Insert spaces between arguments.
5.70 +
5.71 + if first:
5.72 + first = False
5.73 + else:
5.74 + dest.write(" ")
5.75 +
5.76 + dest.write(str(arg))
5.77 +
5.78 + # Add a newline if specified.
5.79 +
5.80 + if nl:
5.81 + dest.write("\n")
5.82 +
5.83 # vim: tabstop=4 expandtab shiftwidth=4
6.1 --- a/lib/native.py Fri Nov 11 00:03:05 2016 +0100
6.2 +++ b/lib/native.py Fri Nov 11 00:05:34 2016 +0100
6.3 @@ -63,4 +63,7 @@
6.4
6.5 def _isinstance(obj, cls): pass
6.6
6.7 +def _read(fd, n): pass
6.8 +def _write(fd, str): pass
6.9 +
6.10 # vim: tabstop=4 expandtab shiftwidth=4
7.1 --- a/lib/sys.py Fri Nov 11 00:03:05 2016 +0100
7.2 +++ b/lib/sys.py Fri Nov 11 00:05:34 2016 +0100
7.3 @@ -21,20 +21,17 @@
7.4
7.5 from native import _exit
7.6
7.7 -# Placeholders for run-time data.
7.8 +# Standard streams.
7.9
7.10 -stdin = file()
7.11 -stdout = file()
7.12 -stderr = file()
7.13 +stdin = sysfile(0)
7.14 +stdout = sysfile(1)
7.15 +stderr = sysfile(2)
7.16 +
7.17 +# NOTE: Environment details to be implemented.
7.18
7.19 argv = []
7.20 path = []
7.21
7.22 -hexversion = 0x20703f0 # 2.7.3 final 0
7.23 -maxint = 2147483647 # 2**31 - 1
7.24 -maxunicode = 1114111
7.25 -platform = 'posix'
7.26 -
7.27 # Functions to be implemented natively.
7.28
7.29 def exit(status=0):
8.1 --- a/templates/native.c Fri Nov 11 00:03:05 2016 +0100
8.2 +++ b/templates/native.c Fri Nov 11 00:05:34 2016 +0100
8.3 @@ -1,4 +1,5 @@
8.4 #include <stdlib.h> /* calloc, exit */
8.5 +#include <unistd.h> /* read, write */
8.6 #include "types.h"
8.7 #include "exceptions.h"
8.8 #include "ops.h"
8.9 @@ -368,6 +369,30 @@
8.10 #undef cls
8.11 }
8.12
8.13 +__attr __fn_native__read(__attr __args[])
8.14 +{
8.15 + #define fd (__args[1])
8.16 + #define n (__args[2])
8.17 +
8.18 + /* NOTE: To be written. */
8.19 + return __builtins___none_None;
8.20 + #undef fd
8.21 + #undef n
8.22 +}
8.23 +
8.24 +__attr __fn_native__write(__attr __args[])
8.25 +{
8.26 + #define fd (__args[1])
8.27 + #define str (__args[2])
8.28 +
8.29 + /* NOTE: To be written. */
8.30 + return __builtins___none_None;
8.31 + #undef fd
8.32 + #undef str
8.33 +}
8.34 +
8.35 +/* Module initialisation. */
8.36 +
8.37 void __main_native()
8.38 {
8.39 }
9.1 --- a/templates/native.h Fri Nov 11 00:03:05 2016 +0100
9.2 +++ b/templates/native.h Fri Nov 11 00:05:34 2016 +0100
9.3 @@ -37,6 +37,11 @@
9.4 __attr __fn_native__tuple_len(__attr __args[]);
9.5 __attr __fn_native__tuple_element(__attr __args[]);
9.6 __attr __fn_native__isinstance(__attr __args[]);
9.7 +__attr __fn_native__read(__attr __args[]);
9.8 +__attr __fn_native__write(__attr __args[]);
9.9 +
9.10 +/* Module initialisation. */
9.11 +
9.12 void __main_native();
9.13
9.14 #endif /* __NATIVE_H__ */
10.1 --- a/tests/assign_sequence.py Fri Nov 11 00:03:05 2016 +0100
10.2 +++ b/tests/assign_sequence.py Fri Nov 11 00:05:34 2016 +0100
10.3 @@ -3,6 +3,9 @@
10.4 x = l
10.5 a, b, c = l
10.6 d, e, f = [1, 2, 3]
10.7 + print a, b, c
10.8 + print d, e, f
10.9 + print x
10.10
10.11 def g(x):
10.12 l = [1, 2, 3]
10.13 @@ -11,13 +14,18 @@
10.14 n = l
10.15 else:
10.16 n = m
10.17 + print n
10.18
10.19 l = [1, 2, 3]
10.20 x = l
10.21 a, b, c = l
10.22 d, e, f = [1, 2, 3]
10.23 +print a, b, c
10.24 +print d, e, f
10.25 +print x
10.26 m = [4, l, 6]
10.27 if x:
10.28 n = l
10.29 else:
10.30 n = m
10.31 +print n
11.1 --- a/translator.py Fri Nov 11 00:03:05 2016 +0100
11.2 +++ b/translator.py Fri Nov 11 00:05:34 2016 +0100
11.3 @@ -536,6 +536,11 @@
11.4 elif isinstance(n, compiler.ast.Return):
11.5 return self.process_return_node(n)
11.6
11.7 + # Print statements.
11.8 +
11.9 + elif isinstance(n, (compiler.ast.Print, compiler.ast.Printnl)):
11.10 + self.statement(self.process_print_node(n))
11.11 +
11.12 # Invocations.
11.13
11.14 elif isinstance(n, compiler.ast.CallFunc):
11.15 @@ -914,6 +919,12 @@
11.16 if not args[argnum+1]:
11.17 args[argnum+1] = "__GETDEFAULT(&%s, %d)" % (target_structure, i)
11.18
11.19 + # Test for missing arguments.
11.20 +
11.21 + if None in args:
11.22 + raise TranslateError("Not all arguments supplied.",
11.23 + self.get_namespace_path(), n)
11.24 +
11.25 # Encode the arguments.
11.26
11.27 argstr = "__ARGS(%s)" % ", ".join(args)
11.28 @@ -1041,15 +1052,11 @@
11.29 if n.name in predefined_constants:
11.30 return PredefinedConstantRef(n.name)
11.31
11.32 - # Convert literal references.
11.33 + # Convert literal references, operator function names, and print
11.34 + # function names to references.
11.35
11.36 - elif n.name.startswith("$L"):
11.37 - ref = self.importer.get_module(self.name).special.get(n.name)
11.38 - return TrResolvedNameRef(n.name, ref)
11.39 -
11.40 - # Convert operator function names to references.
11.41 -
11.42 - elif n.name.startswith("$op"):
11.43 + elif n.name.startswith("$L") or n.name.startswith("$op") or \
11.44 + n.name.startswith("$print"):
11.45 ref = self.importer.get_module(self.name).special.get(n.name)
11.46 return TrResolvedNameRef(n.name, ref)
11.47