Make print() a function before it's too late

This commit is contained in:
K Lange 2021-01-04 23:33:43 +09:00
parent d87fd9b1bd
commit ff8ed02ebd
40 changed files with 358 additions and 345 deletions

153
README.md
View File

@ -28,40 +28,45 @@ _**NOTE**: Due to limitations with Github's markdown renderer, these snippets wi
### Hello World
Kuroko inherits a print statement from its Lox roots, which is similar to the one in Python 2:
```py
print "Hello, world!"
print("Hello, world!")
# → Hello, world!
```
Multiple expressions can be supplied to `print` and will be concatenated with spaces:
```py
print "Hello", 42, "!"
print("Hello", 42, "!")
# → Hello 42 !
```
The string used to combine arguments can be changed with `sep=`.
```py
print("Hello", 42, "!", sep="...")
# → Hello...42...!
```
### Basic Types
Kuroko's basic types are integers (which use the platform `long` type), double-precision floats, booleans (`True` and `False`), and `None`.
```py
print 1 + 2 + 3
print(1 + 2 + 3)
# → 6
```
When integer values are used in arithmetic operations, such as division, the result will be an integer as well:
```py
print 1 / 2
print(1 / 2)
# → 0
```
To get floating-point results, one of the arguments should be explicitly typed or converted:
```py
print 1 / 2.0
print(1 / 2.0)
# → 0.5
```
@ -69,10 +74,10 @@ Implicit type conversion occurs late in evaluation, so be careful of integer ove
```py
# Probably not what you want:
print 1000000000 * 1000000000 * 1000000000 * 3.0
print(1000000000 * 1000000000 * 1000000000 * 3.0)
# → -2.07927e+19
# Try something like this instead:
print 1000000000.0 * 1000000000 * 1000000000 * 3.0
print(1000000000.0 * 1000000000 * 1000000000 * 3.0)
# → 3e+27
```
@ -87,7 +92,7 @@ Objects are passed by reference, though strings are immutable so this property i
Strings can be concatenated, and other values can be appended to them.
```py
print "Hello, " + 42 + "!"
print("Hello, " + 42 + "!")
# → Hello, 42!
```
@ -97,7 +102,7 @@ Function syntax is essentially the same as in Python:
```py
def greet(name):
print "Hello, " + name + "!"
print("Hello, " + name + "!")
greet("user")
# → Hello, user!
```
@ -107,9 +112,9 @@ Default arguments can be specified as follows:
```py
def greet(name=None):
if not name:
print "Hello, world!"
print("Hello, world!")
else:
print "Hello, " + name + "!"
print("Hello, " + name + "!")
greet()
gree("user")
# → Hello, world!
@ -126,14 +131,14 @@ Tabs are not valid as indentation and will be ignored. It is recommended that yo
```py
if False:
print "Oh no, that was a tab."
print("Oh no, that was a tab.")
# → Oh no, that was a tab.
```
Blocks can also accept a single inline statement:
```py
if True: print "The first rule of Tautology Club is the first rule of Tautology Club."
if True: print("The first rule of Tautology Club is the first rule of Tautology Club.")
# → The first rule of Tautology Club is the first rule of Tautology Club.
```
@ -143,10 +148,10 @@ In a departure from Python, Kuroko has explicit variable declaration and traditi
```py
let foo
print foo
print(foo)
# → None
foo = 1
print foo
print(foo)
# → 1
```
@ -160,7 +165,7 @@ When a function references local values from an outter scope, such as in the exa
def foo():
let i = 1 # Local to this call to foo()
def bar():
print i # Reference to outer variable
print(i) # Reference to outer variable
i = i + 1
return bar # Produces a closure
let a = foo() # Each copy of `bar` gets its own `i`
@ -189,7 +194,7 @@ To create a basic object without methods, the `object` class is provided:
```py
let o = object()
o.foo = "bar"
print o.foo
print(o.foo)
# → bar
```
@ -198,7 +203,7 @@ To supply methods, define a class:
```py
class Foo():
def printFoo():
print self.foo
print(self.foo)
let o = Foo()
o.foo = "bar"
o.printFoo()
@ -210,7 +215,7 @@ The `self` keyword is implicit in all methods and does not need to be supplied i
```py
class Foo():
def printFoo(self):
print self.foo
print(self.foo)
let o = Foo()
o.foo = "bar"
o.printFoo()
@ -224,7 +229,7 @@ class Foo():
def __init__(bar):
self.foo = bar
def printFoo(self):
print self.foo
print(self.foo)
let o = Foo("bar")
o.printFoo()
# → bar
@ -243,7 +248,7 @@ class Foo():
def __init__():
self.type = "foo"
def printType():
print self.type
print(self.type)
class Bar(Foo):
def __init__():
@ -261,14 +266,14 @@ class Foo():
def __init__():
self.type = "foo"
def printType():
print self.type
print(self.type)
class Bar(Foo):
def __init__():
self.type = "bar"
def printType():
super().printType()
print "Also, I enjoy long walks on the beach."
print("Also, I enjoy long walks on the beach.")
let bar = Bar()
bar.printType()
@ -283,7 +288,7 @@ class Foo:
class Bar:
class Baz(Bar):
let b = Baz()
print isinstance(b,Baz), isinstance(b,Bar), isinstance(b,Foo), isinstance(b,object)
print(isinstance(b,Baz), isinstance(b,Bar), isinstance(b,Foo), isinstance(b,object))
# → True, True, False, True
```
@ -299,15 +304,15 @@ l.append(1)
l.append(2)
l.append("three")
l.append(False)
print l
print(l)
# → [1, 2, three, False]
l[1] = 5
print l
print(l)
# → [1, 5, three, False]
let d = dict()
d["foo"] = "bar"
d[1] = 2
print d
print(d)
# → {1: 2, foo: bar}
```
@ -315,10 +320,10 @@ These built-in collections can also be initialized as expressions, which act as
```py
let l = [1,2,"three",False] # or listOf(1,2,"three",False)
print l
print(l)
# → [1, 2, three, False]
let d = {"foo": "bar", 1: 2} # or dictOf("foo","bar",1,2)
print d
print(d)
# → {1: 2, foo: bar}
```
@ -326,7 +331,7 @@ Lists can also be generated dynamically:
```py
let fives = [x * 5 for x in [1,2,3,4,5]]
print fives
print(fives)
# → [5, 10, 15, 20, 25]
```
@ -336,7 +341,7 @@ Kuroko provides a mechanism for handling errors at runtime. If an error is not c
```py
def foo(bar):
print "I expect an argument! " + bar
print("I expect an argument! " + bar)
foo() # I didn't provide one!
# → Traceback, most recent first, 1 call frame:
# File "<stdin>", line 1, in <module>
@ -347,11 +352,11 @@ To catch exceptions, use `try`/`except`:
```py
def foo(bar):
print "I expect an argument! " + bar
print("I expect an argument! " + bar)
try:
foo() # I didn't provide one!
except:
print "oh no!"
print("oh no!")
# → oh no!
```
@ -359,11 +364,11 @@ Runtime exceptions are passed to the `except` block as a special variable `excep
```py
def foo(bar):
print "I expect an argument! " + bar
print("I expect an argument! " + bar)
try:
foo() # I didn't provide one!
except:
print "oh no, there was an exception: " + exception.arg
print("oh no, there was an exception:", exception.arg)
# → oh no, there was an exception: foo() takes exactly 1 argument (0 given)
```
@ -373,7 +378,7 @@ Exceptions can also be generated from code:
def login(password):
if password != "supersecret":
raise "Wrong password, try again!"
print "[Hacker voice] I'm in."
print("[Hacker voice] I'm in.")
login("foo")
# → Traceback, most recent first, 2 call frames:
# File "<stdin>", line 5, in <module>
@ -387,7 +392,7 @@ The `except` block is optional, and an exception may be caught and ignored.
def login(password):
if password != "supersecret":
raise "Wrong password, try again!"
print "[Hacker voice] I'm in."
print("[Hacker voice] I'm in.")
try:
login("foo")
# (no output)
@ -407,7 +412,7 @@ return module
```py
# demo.krk
import demomodule
print demomodule.foo
print(demomodule.foo)
# → bar
```
@ -426,7 +431,7 @@ return module
```py
# demo.krk
import demomodule
print foo
print(foo)
# → bar
```
@ -437,7 +442,7 @@ Kuroku supports C-style for loops, while loops, and Python-style iterator for lo
```py
for i = 1, i < 5, i = i + 1:
print i
print(i)
# → 1
# 2
# 3
@ -448,7 +453,7 @@ for i = 1, i < 5, i = i + 1:
let i = 36
while i > 1:
i = i / 2
print i
print(i)
# → 18
# 9
# 4
@ -459,7 +464,7 @@ while i > 1:
```py
let l = [1,2,3]
for i in l:
print i
print(i)
# → 1
# 2
# 3
@ -493,7 +498,7 @@ Objects which have an `__iter__` method can then be used with the `for ... in ..
```py
for i in range(1,5):
print i
print(i)
# → 1
# 2
# 3
@ -507,12 +512,12 @@ Objects with the methods `__get__` and `__set__` can be used with square bracket
```py
class Foo:
def __get__(ind):
print "You asked for ind=" + ind
print("You asked for ind=" + ind)
return ind * 5
def __set__(ind, val):
print "You asked to set ind=" + ind + " to " + val
print("You asked to set ind=" + ind + " to " + val)
let f = Foo()
print f[4]
print(f[4])
f[7] = "bar"
# → You asked for ind=4
# 20
@ -524,11 +529,11 @@ f[7] = "bar"
Substrings can be extracted from strings via slicing:
```py
print "Hello world!"[3:8]
print("Hello world!"[3:8])
# → lo wo
print "Hello world!"[:-1]
print("Hello world!"[:-1])
# → Hello world
print "Hello world!"[-1:]
print("Hello world!"[-1:])
# → !
```
@ -543,7 +548,7 @@ class Foo:
def __str__():
return "(I am a Foo!)"
let f = Foo()
print f
print(f)
# → (I am a Foo!)
```
@ -556,7 +561,7 @@ To open and read the contents of a file:
```py
import fileio
let f = fileio.open("README.md","r")
print f.read()
print(f.read())
f.close()
```
@ -581,7 +586,7 @@ while True:
data = data[:-1]
if data == "exit":
break
print "You said '" + data + "'!"
print("You said '" + data + "'!")
```
### Decorators
@ -590,16 +595,16 @@ Decorators allow functions and methods to be wrapped.
```py
def decorator(func):
print "I take the function to be decorated as an argument:", func
print("I take the function to be decorated as an argument:", func)
def wrapper():
print "And I am the wrapper."
print("And I am the wrapper.")
func()
print "Returned from wrapped function."
print("Returned from wrapped function.")
return wrapper
@decorator
def wrappedFunction():
print "Hello, world"
print("Hello, world")
wrappedFunction()
# → I take a function to be decorated as an argument: <function wrappedFunction>
@ -616,14 +621,14 @@ Method wrappers work similarly, though be sure to explicitly provide a name (oth
def methodDecorator(method):
def methodWrapper(instance, anExtraArgument):
method(instance)
print "I also required this extra argument:", anExtraArgument
print("I also required this extra argument:", anExtraArgument)
return methodWrapper
class Foo():
@methodDecorator
def theMethod():
print "I am a method, so I can obviously access", self
print "And I also didn't take any arguments, but my wrapper did:"
print("I am a method, so I can obviously access", self)
print("And I also didn't take any arguments, but my wrapper did:")
let f = Foo()
f.theMethod("the newly required argument")
@ -636,12 +641,12 @@ Decorators are _expressions_, just like in Python, so to make a decorator with a
```py
def requirePassword(password):
print "I am creating a decorator."
print("I am creating a decorator.")
def decorator(func):
print "I am wrapping", func, "and attaching",password
print("I am wrapping", func, "and attaching",password)
def wrapper(secretPassword):
if secretPassword != password:
print "You didn't say the magic word."
print("You didn't say the magic word.")
return
func()
return wrapper
@ -649,10 +654,10 @@ def requirePassword(password):
@requirePassword("hunter2")
def superSecretFunction():
print "Welcome!"
print("Welcome!")
superSecretFunction("a wrong password")
print "Let's try again."
print("Let's try again.")
superSecretFunction("hunter2")
# → I am wrapping <function superSecretFunction> and attaching hunter2
# You didn't say the magic word.
@ -666,7 +671,7 @@ Arguments may be passed to a function by specifying their name instead of using
```py
def aFunction(a,b,c):
print a,b,c
print(a,b,c)
aFunction(1,2,3)
aFunction(1,c=3,b=2)
@ -680,7 +685,7 @@ This will be slower in execution than a normal function call, as the interpreter
```py
def aFunction(with=None,lots=None,of=None,default=None,args=None):
print with,lots,of,default,args
print(with,lots,of,default,args)
aFunction(of="hello!")
# → None None hello! None None
@ -694,19 +699,19 @@ The variable marked with `*` will be provided as an ordered `list`, and `**` wil
```py
def takesArgs(*args):
print args
print(args)
takesArgs(1,2,3)
# → [1, 2, 3]
def takesKwargs(**kwargs):
print kwargs
print(kwargs)
takesKwargs(a=1,b=2,c=3)
# → {'a': 1, 'b': 2, 'c': 3}
def takesEither(*args,**kwargs):
print args, kwargs
print(args, kwargs)
takesEither(1,2,a=3,b=4)
# → [1, 2] {'a': 3, 'b': 4}
def takesARequiredAndMore(a,*args):
print a, args
print(a, args)
takesARequiredAndMore(1,2,3,4)
# → 1 [2, 3, 4]
```
@ -718,12 +723,12 @@ When used in a function argument list, `*` and `**` before a list and dict expre
```py
let l = [1,2,3]
def foo(a,b,c):
print a,b,c
print(a,b,c)
foo(*l)
# → 1 2 3
let d = {"foo": "a", "bar": 1}
def func(foo,bar):
print foo, bar
print(foo, bar)
func(**d)
# → a 1
```

View File

@ -88,33 +88,33 @@ const char _builtins_src[] = {
0x61,0x6c,0x6c,0x5f,0x5f,0x28,0x73,0x65,0x6c,0x66,0x2c,0x6f,0x62,0x6a,0x3d,0x4e,
0x6f,0x6e,0x65,0x29,0x3a,0x0a,0x20,0x20,0x69,0x66,0x20,0x6f,0x62,0x6a,0x3a,0x0a,
0x20,0x20,0x20,0x74,0x72,0x79,0x3a,0x0a,0x20,0x20,0x20,0x20,0x70,0x72,0x69,0x6e,
0x74,0x20,0x6f,0x62,0x6a,0x2e,0x5f,0x5f,0x64,0x6f,0x63,0x5f,0x5f,0x0a,0x20,0x20,
0x20,0x65,0x78,0x63,0x65,0x70,0x74,0x3a,0x0a,0x20,0x20,0x20,0x20,0x74,0x72,0x79,
0x3a,0x0a,0x20,0x20,0x20,0x20,0x20,0x70,0x72,0x69,0x6e,0x74,0x20,0x6f,0x62,0x6a,
0x2e,0x5f,0x5f,0x63,0x6c,0x61,0x73,0x73,0x5f,0x5f,0x2e,0x5f,0x5f,0x64,0x6f,0x63,
0x5f,0x5f,0x0a,0x20,0x20,0x20,0x20,0x65,0x78,0x63,0x65,0x70,0x74,0x3a,0x0a,0x20,
0x20,0x20,0x20,0x20,0x70,0x72,0x69,0x6e,0x74,0x20,0x22,0x4e,0x6f,0x20,0x64,0x6f,
0x63,0x73,0x74,0x72,0x69,0x6e,0x67,0x20,0x61,0x76,0x61,0x69,0x61,0x6c,0x62,0x6c,
0x65,0x20,0x66,0x6f,0x72,0x22,0x2c,0x20,0x6f,0x62,0x6a,0x0a,0x20,0x20,0x65,0x6c,
0x73,0x65,0x3a,0x0a,0x20,0x20,0x20,0x70,0x72,0x69,0x6e,0x74,0x20,0x22,0x28,0x49,
0x6e,0x74,0x65,0x72,0x61,0x63,0x74,0x69,0x76,0x65,0x20,0x68,0x65,0x6c,0x70,0x20,
0x69,0x73,0x20,0x6e,0x6f,0x74,0x20,0x79,0x65,0x74,0x20,0x61,0x76,0x61,0x69,0x6c,
0x61,0x62,0x6c,0x65,0x29,0x22,0x0a,0x20,0x64,0x65,0x66,0x20,0x5f,0x5f,0x72,0x65,
0x70,0x72,0x5f,0x5f,0x28,0x73,0x65,0x6c,0x66,0x29,0x3a,0x0a,0x20,0x20,0x72,0x65,
0x74,0x75,0x72,0x6e,0x20,0x27,0x54,0x79,0x70,0x65,0x20,0x68,0x65,0x6c,0x70,0x28,
0x29,0x20,0x66,0x6f,0x72,0x20,0x6d,0x6f,0x72,0x65,0x20,0x68,0x65,0x6c,0x70,0x2c,
0x20,0x6f,0x72,0x20,0x68,0x65,0x6c,0x70,0x28,0x6f,0x62,0x6a,0x29,0x20,0x74,0x6f,
0x20,0x64,0x65,0x73,0x63,0x72,0x69,0x62,0x65,0x20,0x61,0x6e,0x20,0x6f,0x62,0x6a,
0x65,0x63,0x74,0x2e,0x27,0x0a,0x0a,0x6c,0x65,0x74,0x20,0x68,0x65,0x6c,0x70,0x20,
0x3d,0x20,0x48,0x65,0x6c,0x70,0x65,0x72,0x28,0x29,0x0a,0x0a,0x65,0x78,0x70,0x6f,
0x72,0x74,0x20,0x6c,0x69,0x73,0x74,0x2c,0x64,0x69,0x63,0x74,0x2c,0x68,0x65,0x6c,
0x70,0x0a,0x0a,0x5f,0x5f,0x62,0x75,0x69,0x6c,0x74,0x69,0x6e,0x73,0x5f,0x5f,0x2e,
0x6d,0x6f,0x64,0x75,0x6c,0x65,0x5f,0x70,0x61,0x74,0x68,0x73,0x20,0x3d,0x20,0x5b,
0x22,0x2e,0x2f,0x22,0x2c,0x22,0x2e,0x2f,0x6d,0x6f,0x64,0x75,0x6c,0x65,0x73,0x2f,
0x22,0x2c,0x22,0x2f,0x68,0x6f,0x6d,0x65,0x2f,0x6b,0x6c,0x61,0x6e,0x67,0x65,0x2f,
0x50,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6b,0x75,0x72,0x6f,0x6b,0x6f,0x2f,
0x6d,0x6f,0x64,0x75,0x6c,0x65,0x73,0x2f,0x22,0x2c,0x22,0x2f,0x75,0x73,0x72,0x2f,
0x73,0x68,0x61,0x72,0x65,0x2f,0x6b,0x75,0x72,0x6f,0x6b,0x6f,0x2f,0x22,0x5d,0x0a,
0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6f,0x62,0x6a,0x65,0x63,0x74,0x28,0x29,
0x0a,
0x74,0x28,0x6f,0x62,0x6a,0x2e,0x5f,0x5f,0x64,0x6f,0x63,0x5f,0x5f,0x29,0x0a,0x20,
0x20,0x20,0x65,0x78,0x63,0x65,0x70,0x74,0x3a,0x0a,0x20,0x20,0x20,0x20,0x74,0x72,
0x79,0x3a,0x0a,0x20,0x20,0x20,0x20,0x20,0x70,0x72,0x69,0x6e,0x74,0x28,0x6f,0x62,
0x6a,0x2e,0x5f,0x5f,0x63,0x6c,0x61,0x73,0x73,0x5f,0x5f,0x2e,0x5f,0x5f,0x64,0x6f,
0x63,0x5f,0x5f,0x29,0x0a,0x20,0x20,0x20,0x20,0x65,0x78,0x63,0x65,0x70,0x74,0x3a,
0x0a,0x20,0x20,0x20,0x20,0x20,0x70,0x72,0x69,0x6e,0x74,0x28,0x22,0x4e,0x6f,0x20,
0x64,0x6f,0x63,0x73,0x74,0x72,0x69,0x6e,0x67,0x20,0x61,0x76,0x61,0x69,0x61,0x6c,
0x62,0x6c,0x65,0x20,0x66,0x6f,0x72,0x22,0x2c,0x20,0x6f,0x62,0x6a,0x29,0x0a,0x20,
0x20,0x65,0x6c,0x73,0x65,0x3a,0x0a,0x20,0x20,0x20,0x70,0x72,0x69,0x6e,0x74,0x28,
0x22,0x28,0x49,0x6e,0x74,0x65,0x72,0x61,0x63,0x74,0x69,0x76,0x65,0x20,0x68,0x65,
0x6c,0x70,0x20,0x69,0x73,0x20,0x6e,0x6f,0x74,0x20,0x79,0x65,0x74,0x20,0x61,0x76,
0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x29,0x22,0x29,0x0a,0x20,0x64,0x65,0x66,0x20,
0x5f,0x5f,0x72,0x65,0x70,0x72,0x5f,0x5f,0x28,0x73,0x65,0x6c,0x66,0x29,0x3a,0x0a,
0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x27,0x54,0x79,0x70,0x65,0x20,0x68,
0x65,0x6c,0x70,0x28,0x29,0x20,0x66,0x6f,0x72,0x20,0x6d,0x6f,0x72,0x65,0x20,0x68,
0x65,0x6c,0x70,0x2c,0x20,0x6f,0x72,0x20,0x68,0x65,0x6c,0x70,0x28,0x6f,0x62,0x6a,
0x29,0x20,0x74,0x6f,0x20,0x64,0x65,0x73,0x63,0x72,0x69,0x62,0x65,0x20,0x61,0x6e,
0x20,0x6f,0x62,0x6a,0x65,0x63,0x74,0x2e,0x27,0x0a,0x0a,0x6c,0x65,0x74,0x20,0x68,
0x65,0x6c,0x70,0x20,0x3d,0x20,0x48,0x65,0x6c,0x70,0x65,0x72,0x28,0x29,0x0a,0x0a,
0x65,0x78,0x70,0x6f,0x72,0x74,0x20,0x6c,0x69,0x73,0x74,0x2c,0x64,0x69,0x63,0x74,
0x2c,0x68,0x65,0x6c,0x70,0x0a,0x0a,0x5f,0x5f,0x62,0x75,0x69,0x6c,0x74,0x69,0x6e,
0x73,0x5f,0x5f,0x2e,0x6d,0x6f,0x64,0x75,0x6c,0x65,0x5f,0x70,0x61,0x74,0x68,0x73,
0x20,0x3d,0x20,0x5b,0x22,0x2e,0x2f,0x22,0x2c,0x22,0x2e,0x2f,0x6d,0x6f,0x64,0x75,
0x6c,0x65,0x73,0x2f,0x22,0x2c,0x22,0x2f,0x68,0x6f,0x6d,0x65,0x2f,0x6b,0x6c,0x61,
0x6e,0x67,0x65,0x2f,0x50,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6b,0x75,0x72,
0x6f,0x6b,0x6f,0x2f,0x6d,0x6f,0x64,0x75,0x6c,0x65,0x73,0x2f,0x22,0x2c,0x22,0x2f,
0x75,0x73,0x72,0x2f,0x73,0x68,0x61,0x72,0x65,0x2f,0x6b,0x75,0x72,0x6f,0x6b,0x6f,
0x2f,0x22,0x5d,0x0a,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6f,0x62,0x6a,0x65,
0x63,0x74,0x28,0x29,0x0a,
0x00 };

View File

@ -60,14 +60,14 @@ class Helper():
def __call__(self,obj=None):
if obj:
try:
print obj.__doc__
print(obj.__doc__)
except:
try:
print obj.__class__.__doc__
print(obj.__class__.__doc__)
except:
print "No docstring avaialble for", obj
print("No docstring avaialble for", obj)
else:
print "(Interactive help is not yet available)"
print("(Interactive help is not yet available)")
def __repr__(self):
return 'Type help() for more help, or help(obj) to describe an object.'

View File

@ -27,7 +27,6 @@ typedef enum {
OP_EQUAL,
OP_GREATER,
OP_LESS,
OP_PRINT,
OP_DEFINE_GLOBAL,
OP_GET_GLOBAL,
OP_SET_GLOBAL,
@ -72,7 +71,6 @@ typedef enum {
OP_EXPAND_ARGS,
OP_CONSTANT_LONG = 128,
OP_PRINT_LONG,
OP_DEFINE_GLOBAL_LONG,
OP_GET_GLOBAL_LONG,
OP_SET_GLOBAL_LONG,

View File

@ -579,15 +579,6 @@ static void varDeclaration() {
defineVariable(ind);
}
static void printStatement() {
int argCount = 0;
do {
expression();
argCount++;
} while (match(TOKEN_COMMA));
EMIT_CONSTANT_OP(OP_PRINT, argCount);
}
static void synchronize() {
parser.panicMode = 0;
while (parser.current.type != TOKEN_EOF) {
@ -600,7 +591,6 @@ static void synchronize() {
case TOKEN_FOR:
case TOKEN_IF:
case TOKEN_WHILE:
case TOKEN_PRINT:
case TOKEN_RETURN:
return;
default: break;
@ -1336,9 +1326,7 @@ static void statement() {
} else if (check(TOKEN_TRY)) {
tryStatement();
} else {
if (match(TOKEN_PRINT)) {
printStatement();
} else if (match(TOKEN_EXPORT)) {
if (match(TOKEN_EXPORT)) {
exportStatement();
} else if (match(TOKEN_RAISE)) {
raiseStatement();
@ -1734,7 +1722,6 @@ ParseRule rules[] = {
RULE(TOKEN_NONE, literal, NULL, PREC_NONE),
RULE(TOKEN_NOT, unary, not_, PREC_COMPARISON),
RULE(TOKEN_OR, NULL, or_, PREC_OR),
RULE(TOKEN_PRINT, NULL, NULL, PREC_NONE),
RULE(TOKEN_RETURN, NULL, NULL, PREC_NONE),
RULE(TOKEN_SELF, self, NULL, PREC_NONE),
RULE(TOKEN_SUPER, super_, NULL, PREC_NONE),

View File

@ -114,7 +114,6 @@ size_t krk_disassembleInstruction(KrkChunk * chunk, size_t offset) {
OPERAND(OP_SET_UPVALUE)
OPERAND(OP_GET_UPVALUE)
OPERAND(OP_CALL)
OPERAND(OP_PRINT)
OPERAND(OP_INC)
JUMP(OP_JUMP,+)
JUMP(OP_JUMP_IF_FALSE,+)

View File

@ -520,7 +520,7 @@ void paint_krk_string(struct syntax_state * state, int type) {
char * syn_krk_keywords[] = {
"and","class","def","else","export","for","if","in","import",
"let","not","or","print","return","while","try","except","raise",
"let","not","or","return","while","try","except","raise",
"continue","break","as","from","elif",
NULL
};
@ -531,6 +531,7 @@ char * syn_krk_types[] = {
"len", "str", "int", "float", "dir", "repr", /* global functions from __builtins__ */
"list","dict","range", /* builtin classes */
"object","exception","isinstance","type",
"print",
NULL
};

View File

@ -225,7 +225,6 @@ static KrkTokenType identifierType() {
case 'n': return checkKeyword(1, "ot", TOKEN_NOT);
case 'N': return checkKeyword(1, "one", TOKEN_NONE);
case 'o': return checkKeyword(1, "r", TOKEN_OR);
case 'p': return checkKeyword(1, "rint", TOKEN_PRINT);
case 'r': if (MORE(1)) switch (scanner.start[1]) {
case 'e': return checkKeyword(2, "turn", TOKEN_RETURN);
case 'a': return checkKeyword(2, "ise", TOKEN_RAISE);

View File

@ -31,7 +31,7 @@ typedef enum {
TOKEN_NONE, /* 36 None */
TOKEN_NOT, /* 37 not */
TOKEN_OR, /* 38 or */
TOKEN_PRINT, /* 39 print */
TOKEN_ELIF, /* Provided for compatibility, recommend `else if` instead. */
TOKEN_RETURN,/* 40 return */
TOKEN_SELF, /* 41 self */
TOKEN_SUPER, /* 42 super */
@ -66,7 +66,6 @@ typedef enum {
TOKEN_AS,
TOKEN_FROM,
TOKEN_ELIF, /* Provided for compatibility, recommend `else if` instead. */
TOKEN_ERROR,
TOKEN_EOF,

View File

@ -1,7 +1,7 @@
# Strings have a syntehesized __get__
# which returns an integer value of the byte...
# This will probably codepoint of a UTF-32 string later?
print "Test"[1]
print("Test"[1])
class Test:
def __init__(self):
@ -9,6 +9,6 @@ class Test:
# Instances have a __class__ property synthesized by the VM
let test = Test()
print test.__class__
print(test.__class__)
print (37.45).__int__()
print((37.45).__int__())

View File

@ -10,7 +10,7 @@ for l in lines:
for line in lines:
if (2020 - line) in data:
print line, 2020 - line, line * (2020 - line)
print(line, 2020 - line, line * (2020 - line))
def sums_index(lines, ind):
let out = []
@ -23,5 +23,5 @@ def sums_index(lines, ind):
for ind in range(len(lines)):
for s in sums_index(lines, ind):
if (2020 - s) in lines:
print ((s - lines[ind]) * lines[ind]) * (2020 -s)
print(((s - lines[ind]) * lines[ind]) * (2020 -s))

View File

@ -28,7 +28,7 @@ for line in lines:
let policy_high = int(s[0])
let letter = s[1]
let is_valid = check_second(policy_low, policy_high, letter, password)
print policy_low, policy_high, letter, password, is_valid
print(policy_low, policy_high, letter, password, is_valid)
if is_valid:
valid += 1
print valid
print(valid)

View File

@ -12,9 +12,9 @@ def __main__():
ordering.append(1) # 9 -> 1
ordering.extend(range(11,1000001))
ordering.append(5) # 1,000,000 -> 5
print "Done, ordering is", len(ordering)
print("Done, ordering is", len(ordering))
print "Starting loop..."
print("Starting loop...")
#__builtins__.set_tracing("tracing=1")
let m0 = 5
@ -33,6 +33,6 @@ def __main__():
ordering[m3] = px
m0 = ordering[m0]
print ordering[1]*ordering[ordering[1]]
print(ordering[1]*ordering[ordering[1]])
__main__()

View File

@ -12,5 +12,5 @@ def count_trees(lines, x_off, y_off):
y += y_off
return trees
print "part 1:", count_trees(lines, 3, 1)
print "part 2:", count_trees(lines, 1, 1) * count_trees(lines, 3, 1) * count_trees(lines, 5, 1) * count_trees(lines, 7, 1) * count_trees(lines, 1, 2)
print("part 1:", count_trees(lines, 3, 1))
print("part 2:", count_trees(lines, 1, 1) * count_trees(lines, 3, 1) * count_trees(lines, 5, 1) * count_trees(lines, 7, 1) * count_trees(lines, 1, 2))

View File

@ -18,47 +18,47 @@ def is_digits(val, cnt):
return not any([x not in '0123456789' for x in val])
def check_passport(passport):
print "Checking",passport
print("Checking",passport)
let expected = ['byr','iyr','eyr','hgt','hcl','ecl','pid']
if not all([e in passport for e in expected]):
print 'Missing expected value'
print('Missing expected value')
return 0
#return 1
if not is_digits(passport['byr'], 4) or int(passport['byr']) < 1920 or int(passport['byr']) > 2002:
print 'Bad birth year'
print('Bad birth year')
return 0
if not is_digits(passport['iyr'], 4) or int(passport['iyr']) < 2010 or int(passport['iyr']) > 2020:
print 'Bad issue year'
print('Bad issue year')
return 0
if not is_digits(passport['eyr'], 4) or int(passport['eyr']) < 2020 or int(passport['eyr']) > 2030:
print 'Bad expire year'
print('Bad expire year')
return 0
if passport['hgt'][-2:] == 'cm':
if not is_digits(passport['hgt'][:-2], 3) or int(passport['hgt'][:-2]) < 150 or int(passport['hgt'][:-2]) > 193:
print 'bad height in cm'
print('bad height in cm')
return 0
elif passport['hgt'][-2:] == 'in':
if not is_digits(passport['hgt'][:-2], 2) or int(passport['hgt'][:-2]) < 59 or int(passport['hgt'][:-2]) > 76:
print 'bad height in inches:', int(passport['hgt'][:-2])
print('bad height in inches:', int(passport['hgt'][:-2]))
return 0
else:
print 'bad height generally'
print('bad height generally')
return 0
if len(passport['hcl']) != 7 or passport['hcl'][0] != '#' or any([x not in '0123456789abcdef' for x in passport['hcl'][1:]]):
print 'bad hair color'
print('bad hair color')
return 0
if passport['ecl'] not in ['amb','blu','brn','gry','grn','hzl','oth']:
print 'bad eye color'
print('bad eye color')
return 0
if not is_digits(passport['pid'], 9):
print 'bad pid'
print('bad pid')
return 0
return 1
@ -76,4 +76,4 @@ for line in lines:
passport[s[0]] = s[1]
count += check_passport(passport)
print "count =", count
print("count =", count)

View File

@ -27,8 +27,8 @@ def process_seat(seat):
size = size / 2
return bottom
print process_row("FBFBBFFRLR") # 44
print process_seat("FBFBBFFRLR") # 5
print(process_row("FBFBBFFRLR")) # 44
print(process_seat("FBFBBFFRLR")) # 5
def seat_id(seat):
let row = process_row(seat)
@ -41,7 +41,7 @@ for l in lines:
if i > top:
top = i
print top # Answer to part 1, should be 953
print(top) # Answer to part 1, should be 953
let taken = {}
@ -69,9 +69,9 @@ def max(iter):
l = v
return l
print "---"
print("---")
for i in range(min(taken.keys()), max(taken.keys())):
if (i - 1) in taken and (i + 1) in taken and i not in taken:
print i
print(i)
# Should print once, 615

View File

@ -13,7 +13,7 @@ for line in lines:
a[c] = 1
b += len(a)
print b # 6430
print(b) # 6430
def count(d):
let c = 0
@ -40,4 +40,4 @@ for line in lines:
a[c] = 0
b += count(a)
print b # 3125
print(b) # 3125

View File

@ -10,5 +10,5 @@ for x in range(1,1000):
f.write(",")
f.write("\"applesauce\"]\n")
f.write("print l\n")
f.write("print(l)\n")
f.close()

View File

@ -4,49 +4,43 @@ import time
# set to Python. Not even bim has a highlighter for Kuroko yet.
if False:
print "Kuroko has Python-style syntax"
print "with significant whitespace."
print("Kuroko has Python-style syntax")
print("with significant whitespace.")
print "Blank lines are ignored."
print("Blank lines are ignored.")
# Comments should work, too.
print "None of this should print, since it's in an `if False:`"
print("None of this should print, since it's in an `if False:`")
# Coincidentally, Lox has a print statement like Python 2 did.
# I don't know if I'll keep it (haven't we all moved on to Python 3?)
# but for now it's what we have. You _can_ put parens around print values,
# including immediately after the 'print' token, and it'll work just fine.
# Actually the way the scanner works, there's a lot of stuff that doesn't
# need whitespace even though you might think it should have it...
print "This is the first line that should print."
print("This is the first line that should print.")
# Concatenation currently requires the first argument be a string.
# Other values then get converted to strings as you go.
print "We can do simple concatenation " + 123 + "."
print("We can do simple concatenation " + 123 + ".")
# Lox only has a 'Number' type for numerical values, but we have
# Integer and Floating to separate the two.
print 4.2 * 9.7 # Should be 40.74
print 1 + 2 + 3
print(4.2 * 9.7) # Should be 40.74
print(1 + 2 + 3)
# Other bases:
print "Hex: " + 0xFF + " Octal: " + 0o123 + " Binary: " + 0b1010
print("Hex: " + 0xFF + " Octal: " + 0o123 + " Binary: " + 0b1010)
# This `for init, cond, step:` syntax is possibly temporary? I do intend to
# implement iterators and `for VAR in ITER:` like in Python, but C-style for
# loops are also useful...
for i = 0, i < 10, i = i + 1:
print "i = " + i
print("i = " + i)
# Functions work like in Python, though currently no default values.
def function(arg): # And of course the parser will handle comments here...
print "This is a function that does a thing!"
print("This is a function that does a thing!")
if arg == "demo": # Or here...
print "You passed 'demo' as an argument!"
print("You passed 'demo' as an argument!")
else: # And definitely here.
print "You passed something else."
print("You passed something else.")
return 42
print "This code is after the function definition"
print("This code is after the function definition")
# While I'm following the book, variable declarations are explicit with `let`.
# I don't know if I want to implement Python's scoping rules, which are a bit
@ -55,7 +49,7 @@ print "This code is after the function definition"
# now we're following traditional scoping rules, and a simple `let foo` at
# the head of the appropriate block should work okay.
let result = function("demo")
print "The function call returned: " + result
print("The function call returned: " + result)
# `sleep()` is a native function bind. Lox has `clock` as an example, but I
# figured something with arguments would be more useful? The purpose of this
@ -63,7 +57,7 @@ print "The function call returned: " + result
# plugins for bim, so native bindings are going to be very important.
result = time.sleep(0.1)
print "Call to sleep returned: " + result
print("Call to sleep returned: " + result)
function("something else")
@ -74,13 +68,13 @@ let funcs = Funcs()
if True:
let a = 1
def f():
print a
print(a)
let b = 2
def g():
print b
print(b)
let c = 3
def h():
print c
print(c)
funcs.f = f
funcs.g = g
@ -92,17 +86,17 @@ def outer(): # test
#multiple lines
let x = "outside"
def inner():
print x
print(x)
return inner
print "Function is defined, creating it..."
print("Function is defined, creating it...")
let closure = outer()
print "And executing the result..."
print("And executing the result...")
# This should correctly print "outside"
closure()
# This is surprisingly similar to Python already...
print "Let's do some classes."
print("Let's do some classes.")
class Test: # This is a test class
# `self` is actually optional - it's implictly passed.
# If you include it in a parameter list, it's completely ignored.
@ -111,15 +105,15 @@ class Test: # This is a test class
# Look, a method!
def doAThing():
print "yay: " + self.foo
print("yay: " + self.foo)
print Test
print(Test)
let test = Test()
#print test # Removed because of pointer output
#print(test) # Removed because of pointer output
test.doAThing()
test.foo = "bar"
print test.foo
print test.doAThing
print(test.foo)
print(test.doAThing)
test.doAThing()
@ -127,13 +121,13 @@ class SuperClass():
def __init__(self):
self.a = "class"
def aMethod(self):
print "This is a great " + self.a + "!"
print("This is a great " + self.a + "!")
def __str__(self):
return "(I am a " + self.a + ")"
def __get__(self, ind):
return "(get[" + ind + "])"
def __set__(self, ind, val):
print "(set[" + ind + "] = " + val + ")"
print("(set[" + ind + "] = " + val + ")")
class SubClass(SuperClass):
def __init__(self):
@ -143,35 +137,35 @@ let subclass = SubClass()
subclass.aMethod()
# Nope
#print self
#print(self)
# Also nope
#def notAMethod():
# print self
# print(self)
# Definitely nope
#def notAMethoDeither(self):
# print self
# print(self)
print "Subclass says: " + subclass
print("Subclass says: " + subclass)
subclass.__get__(123)
print subclass[123]
print(subclass[123])
subclass[456] = "test"
print "Let's make a hashmap:"
print("Let's make a hashmap:")
let hash = dict()
hash["hello"] = "world"
print hash["hello"]
print(hash["hello"])
print "Let's make some lists:"
print("Let's make some lists:")
let l = list()
print "Length before: " + len(l)
print("Length before: " + len(l))
l.append(1)
l.append(2)
l.append(3)
print "Length after: " + len(l)
print("Length after: " + len(l))
for j = 0, j < len(l), j = j + 1:
print "j=" + j + ", list[j]=" + l[j]
print("j=" + j + ", list[j]=" + l[j])
print "Can we call properties of strings?".__len__() # Of course we can.
print("Can we call properties of strings?".__len__()) # Of course we can.
return 0

View File

@ -1,19 +1,19 @@
def anything(*args, **kwargs):
print "Positionals:", args
print "Keywords:", kwargs
print("Positionals:", args)
print("Keywords:", kwargs)
anything(1,2,3,"a","b",foo="bar",biz=42)
def func(a,b,*args,**kwargs):
print a, b, args
print(a, b, args)
let x = 'hello'
print x
print(x)
func(1,2,3,4,5,6,foo="bar")
def last(a,b,c=1,d=2,**kwargs):
print "Main:", a, b, c, d
print "Keyword:", kwargs
print("Main:", a, b, c, d)
print("Keyword:", kwargs)
last(1,2)
last(1,2,7,3)
@ -21,4 +21,4 @@ last(1,2,test="thing")
try:
last(1,2,'c','d',7,8,extra='foo')
except:
print exception.arg
print(exception.arg)

View File

@ -1,6 +1,6 @@
def func(a,b,*args,**kwargs):
print "a =",a,"b =",b
print "args =",args,"kwargs =",kwargs
print("a =",a,"b =",b)
print("args =",args,"kwargs =",kwargs)
print "\[[31mCall starts here.\[[0m"
print("\[[31mCall starts here.\[[0m")
func(1,*[1,2,3],**{"foo":"bar"},stuff="things")

View File

@ -1,97 +1,97 @@
def decorator(func):
def wrapper(butts):
print "I am a great decorated function that now needs an argument!", butts
print("I am a great decorated function that now needs an argument!", butts)
func()
print "And this is after the function call."
print "Decorating!"
print("And this is after the function call.")
print("Decorating!")
return wrapper
print "Decorator defined."
print("Decorator defined.")
@decorator
def foo():
print "Bar"
print("Bar")
print "Function with decorator defined."
print("Function with decorator defined.")
foo("I am the argument")
print "Function with decorator called."
print("Function with decorator called.")
def __main__():
def decorator(func):
def wrapper(butts):
print "I am a great decorated function (within a function!) that now needs an argument!", butts
print("I am a great decorated function (within a function!) that now needs an argument!", butts)
func()
print "And this is after the function call (in a function call!)"
print "Decorating!"
print("And this is after the function call (in a function call!)")
print("Decorating!")
return wrapper
print "Decorator defined."
print("Decorator defined.")
let i = 42
let l = [1,2,3]
@decorator
def foo():
print "Bar (the inner one)"
print("Bar (the inner one)")
print "Function with decorator defined."
print("Function with decorator defined.")
foo("I am in the inner wrapper.")
print "Function with decorator called."
print("Function with decorator called.")
print "I like the numbers", l
print("I like the numbers", l)
print "Calling main."
print("Calling main.")
__main__()
def methodDecorator(func):
def wrappedMethod(instance, butts):
print "I need an extra arg:", butts
print("I need an extra arg:", butts)
func(instance)
print "Done."
print("Done.")
return wrappedMethod
class Foo():
def __init__(self):
self.foo = "bar"
print "I am an initializer."
print("I am an initializer.")
def undecorated(self):
print "I am here."
print "self.foo =", self.foo
print("I am here.")
print("self.foo =", self.foo)
@methodDecorator
def decorated(self):
print "(decorated) self.foo = ", self.foo
print("(decorated) self.foo = ", self.foo)
let f = Foo()
f.undecorated()
print "Returned from f.undecorated()"
print("Returned from f.undecorated()")
f.decorated("butts")
print "Returned from f.decorated()"
print("Returned from f.decorated()")
def decoratorWithArgument(decoratorArg):
def theActualDecorator(func):
print "I am decorating",func,"with this argument:",decoratorArg
print("I am decorating",func,"with this argument:",decoratorArg)
def wrapped():
print "This wrapper captured this decorator arg:", decoratorArg
print("This wrapper captured this decorator arg:", decoratorArg)
func()
return wrapped
return theActualDecorator
@decoratorWithArgument("foo")
def decoratedWithArgument():
print "I don't take any args of mine own, and nor does my wrapper."
print("I don't take any args of mine own, and nor does my wrapper.")
decoratedWithArgument()
def methodDecoratorWithArguments(decoratorArgA, decoratorArgB):
def theActualDecorator(method):
print "I am decorating", method, "with these args:", decoratorArgA, decoratorArgB
print("I am decorating", method, "with these args:", decoratorArgA, decoratorArgB)
def wrapped(instance, wrapperArg):
print "I captured these from the decorator:", decoratorArgA, decoratorArgB
print "I also take my own argument:", wrapperArg
print("I captured these from the decorator:", decoratorArgA, decoratorArgB)
print("I also take my own argument:", wrapperArg)
method(instance,"and modify this one")
return wrapped
return theActualDecorator
@ -102,26 +102,26 @@ class Bar():
@methodDecoratorWithArguments("foo","bar")
def superDecoratedMethod(self, arg):
print "I am method, so I can access myself", self.foo, "and also my own argument which is now", arg
print("I am method, so I can access myself", self.foo, "and also my own argument which is now", arg)
let b = Bar()
b.superDecoratedMethod("this arg goes to the wrapper")
def genericDecorator(func):
def wrapper(*args,**kwargs):
print "I am a generic wrapper, I will pass all of my args along."
print("I am a generic wrapper, I will pass all of my args along.")
func(*args,**kwargs)
print "And I am done."
print("And I am done.")
return wrapper
@genericDecorator
def aMethod(with,args=None):
print "I got",with,"and",args
print("I got",with,"and",args)
try:
aMethod()
except:
print exception.arg
print(exception.arg)
aMethod("just the first")
aMethod("the first","and the second")
@ -129,10 +129,10 @@ aMethod(args="hello",with="world")
try:
aMethod(foo="hello",with="bar")
except:
print exception.arg # unrecognized keyword arg, from inner method
print(exception.arg) # unrecognized keyword arg, from inner method
aMethod(*[1,2])
try:
aMethod(*[1,2,3])
except:
print exception.arg # too many arguments
print(exception.arg) # too many arguments

View File

@ -1,20 +1,20 @@
def foo(default="bacon"):
print "You like",default,"right?"
print("You like",default,"right?")
foo()
foo("sports")
def fillValues(a=1,b=2,c="c",d=None,e=2.71828):
print a,b,c,d,e
print(a,b,c,d,e)
fillValues(b=True)
fillValues(c="test",a="one",e=object)
# Not like in Python! This is absolutely an anti-feature in Python.
def alwaysAFreshList(l=[]):
print "l=",l
print("l=",l)
l.append(1)
print "l*=",l
print("l*=",l)
alwaysAFreshList()
alwaysAFreshList()

View File

@ -1,5 +1,5 @@
def foo(a,b,c,d):
print a,b,c,d
print(a,b,c,d)
foo(
@ -14,8 +14,8 @@ let l = [
3,4
]
print l
print(l)
for i in [1,2,
3,4]:
print "lol",i
print("lol",i)

View File

@ -1,12 +1,12 @@
let x = 2
if x == 1:
print "one"
print("one")
else if x == 2:
print "two"
print("two")
else if x == 3:
print "three"
print("three")
else:
print "something else"
print("something else")
print "outside of if/else"
print("outside of if/else")

View File

@ -3,16 +3,16 @@ class AClass():
"""A docstring"""
def foo(self):
print "class member foo"
print("class member foo")
# What about blank lines?
def bar(self):
print "class member bar"
print("class member bar")
# Oh my.
let a = AClass()
a.foo()
a.bar()
print AClass.__doc__
print(AClass.__doc__)

View File

@ -6,7 +6,7 @@ h[1] = 2
h[3] = 4
for v in h.keys():
print v
print(v)
for v in h.keys():
print "" + v + ": " + h[v]
print("" + v + ": " + h[v])

View File

@ -1,6 +1,6 @@
def function(positional1, positional2, keyword1=None, keyword2=None):
print positional1, positional2
print keyword1, keyword2
print(positional1, positional2)
print(keyword1, keyword2)
function(1,2)
function(1,2,3,4)
@ -10,21 +10,21 @@ function(1,2,keyword2=5)
try:
function(1,keyword2=5)
except:
print exception.arg
print(exception.arg)
try:
function(1,2,positional1=4)
except:
print exception.arg
print(exception.arg)
try:
function(1,2,keyword2=None,keyword2=5)
except:
print exception.arg
print(exception.arg)
function(1,keyword2=4,positional2="abc")
try:
function(1,keyword2=4,keyword1=5,positional1="nope")
except:
print exception.arg
print(exception.arg)

View File

@ -3,6 +3,6 @@ import fileio as io
let f = io.open("README.md")
let lines = f.read().split("\n")
print len(lines),"lines"
print(len(lines),"lines")
print lines[1:5]
print(lines[1:5])

View File

@ -1,2 +1,2 @@
767 lines
772 lines
['', 'Kuroko is a bytecode-interpreted, dynamic, strongly-typed language with syntax similar to Python.', '', 'The bytecode VM / compiler is substantially based on Robert Nystrom\'s [_Crafting Interpreters_](https://craftinginterpreters.com/).']

View File

@ -6,12 +6,12 @@ l.append("string")
l.append(3.14159)
def foo():
print "bar"
print("bar")
l.append(foo)
l.append("world")
for v in l:
print v
print(v)
return 0

View File

@ -1,12 +1,12 @@
print [x * 5 for x in [1,2,3,4,5]]
print([x * 5 for x in [1,2,3,4,5]])
print "Continuing..."
print("Continuing...")
# Simple list comprehensions
for i in [x * 5 for x in [1,7,3,5,9,2,8]]:
print i
print(i)
print "Now a sum..."
print("Now a sum...")
def sum(iterable):
let total = 0
@ -14,6 +14,6 @@ def sum(iterable):
total = total + v
return total
print "And now that sum applied to a complicated expression..."
print("And now that sum applied to a complicated expression...")
print sum([x * 3 for x in [y * 7 for y in [1,2,3,4,5]]])
print(sum([x * 3 for x in [y * 7 for y in [1,2,3,4,5]]]))

View File

@ -1,3 +1,3 @@
# This file was generated by generateLongListTest.krk
let l = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999,"applesauce"]
print l
print(l)

View File

@ -7,22 +7,22 @@ while True:
let y = 0
while True:
y = y + 1
print "[ y = ",y,"]"
print("[ y = ",y,"]")
if y == x:
break
print "y = ",y
print("y = ",y)
if x > 10:
print "not going to print this one :)"
print("not going to print this one :)")
continue
print "x = ",x
print "hello",x
print("x = ",x)
print("hello",x)
for i in [1,2,3,4,5,6]:
if i == 2:
print "skipping 2"
print("skipping 2")
continue
if i == 4:
print "4? ending early!"
print("4? ending early!")
break
print i * 5
print "Done"
print(i * 5)
print("Done")

View File

@ -2,7 +2,7 @@
let l = []
def foo(x=l):
x.append("more")
print x
print(x)
foo() # → ['more']
foo() # → ['more', 'more']

View File

@ -3,6 +3,6 @@ import time
try:
time.sleep()
except:
print "oh no! " + exception.arg
print("oh no! " + exception.arg)
print "Back from try/except"
print("Back from try/except")

View File

@ -6,9 +6,9 @@ long string that spans
multiple lines"""
let stringWithLineBreak = "This is a normal string \
with a line break in it!"
with a line break in it!"
print normalString
print singleString
print longString
print stringWithLineBreak
print(normalString)
print(singleString)
print(longString)
print(stringWithLineBreak)

View File

@ -1,5 +1,5 @@
# Strings should support at least some basic escape sequences.
print "hello\nworld \"quotes\""
print("hello\nworld \"quotes\"")
# Should print:
# hello
# world "quotes"

View File

@ -1,29 +1,29 @@
print "Hello, world!"
print("Hello, world!")
try:
print "This is the try block"
print("This is the try block")
let f = 123
print f
print "Blah blah blah"
print "Oh no let's raise an exception!"
print(f)
print("Blah blah blah")
print("Oh no let's raise an exception!")
raise "oh no!"
print "This should not print"
print "Instead we should jump to the except block"
print("This should not print")
print("Instead we should jump to the except block")
except:
print "This is the except block"
print("This is the except block")
let j = 456
print j
print "This is outside of the try-except"
print(j)
print("This is outside of the try-except")
print "Let's try nesting an exception and raising it"
print("Let's try nesting an exception and raising it")
try:
print "This is the top level"
print("This is the top level")
try:
print "This is the inner level"
print("This is the inner level")
raise "This is the exception"
except:
print "This is the inner handler."
print("This is the inner handler.")
raise exception
except:
print "This is the outer handler."
print exception
print("This is the outer handler.")
print(exception)

73
vm.c
View File

@ -1266,6 +1266,41 @@ static KrkValue _char_to_int(int argc, KrkValue argv[]) {
return INTEGER_VAL(AS_CSTRING(argv[0])[0]);
}
static KrkValue _print(int argc, KrkValue argv[], int hasKw) {
KrkValue sepVal, endVal;
char * sep = " ";
char * end = "\n";
if (hasKw) {
argc--;
KrkValue _dict_internal;
krk_tableGet(&AS_INSTANCE(argv[argc])->fields, vm.specialMethodNames[METHOD_DICT_INT], &_dict_internal);
if (krk_tableGet(AS_DICT(_dict_internal), OBJECT_VAL(S("sep")), &sepVal)) {
if (!IS_STRING(sepVal)) {
krk_runtimeError(vm.exceptions.typeError, "'sep' should be a string, not '%s'", krk_typeName(sepVal));
return NONE_VAL();
}
sep = AS_CSTRING(sepVal);
}
if (krk_tableGet(AS_DICT(_dict_internal), OBJECT_VAL(S("end")), &endVal)) {
if (!IS_STRING(endVal)) {
krk_runtimeError(vm.exceptions.typeError, "'end' should be a string, not '%s'", krk_typeName(endVal));
return NONE_VAL();
}
end = AS_CSTRING(endVal);
}
}
for (int i = 0; i < argc; ++i) {
KrkValue printable = argv[i];
if (IS_STRING(printable)) { /* krk_printValue runs repr */
fprintf(stdout, "%s", AS_CSTRING(printable));
} else {
krk_printValue(stdout, printable);
}
fprintf(stdout, "%s", (i == argc - 1) ? end : sep);
}
return NONE_VAL();
}
/* str.__len__() */
static KrkValue _string_length(int argc, KrkValue argv[]) {
if (argc != 1) {
@ -1653,7 +1688,10 @@ static KrkValue _string_split(int argc, KrkValue argv[], int hasKw) {
PUSH_CHAR(*c);
i++; c++;
}
krk_writeValueArray(AS_LIST(_list_internal), OBJECT_VAL(krk_copyString(stringBytes, stringLength)));
KrkValue tmp = OBJECT_VAL(krk_copyString(stringBytes, stringLength));
krk_push(tmp);
krk_writeValueArray(AS_LIST(_list_internal), tmp);
krk_pop();
FREE_ARRAY(char,stringBytes,stringCapacity);
#if 0
/* Need to parse kwargs to support this */
@ -1681,7 +1719,10 @@ static KrkValue _string_split(int argc, KrkValue argv[], int hasKw) {
PUSH_CHAR(*c);
i++; c++;
}
krk_writeValueArray(AS_LIST(_list_internal), OBJECT_VAL(krk_copyString(stringBytes, stringLength)));
KrkValue tmp = OBJECT_VAL(krk_copyString(stringBytes, stringLength));
krk_push(tmp);
krk_writeValueArray(AS_LIST(_list_internal), tmp);
krk_pop();
if (substringMatch(c, self->length - i, AS_STRING(argv[1])->chars, AS_STRING(argv[1])->length)) {
i += AS_STRING(argv[1])->length;
c += AS_STRING(argv[1])->length;
@ -1694,12 +1735,18 @@ static KrkValue _string_split(int argc, KrkValue argv[], int hasKw) {
PUSH_CHAR(*c);
i++; c++;
}
krk_writeValueArray(AS_LIST(_list_internal), OBJECT_VAL(krk_copyString(stringBytes, stringLength)));
KrkValue tmp = OBJECT_VAL(krk_copyString(stringBytes, stringLength));
krk_push(tmp);
krk_writeValueArray(AS_LIST(_list_internal), tmp);
krk_pop();
if (stringBytes) FREE_ARRAY(char,stringBytes,stringCapacity);
break;
}
if (i == self->length) {
krk_writeValueArray(AS_LIST(_list_internal), OBJECT_VAL(S("")));
KrkValue tmp = OBJECT_VAL(S(""));
krk_push(tmp);
krk_writeValueArray(AS_LIST(_list_internal), tmp);
krk_pop();
}
}
}
@ -2268,6 +2315,7 @@ void krk_initVM(int flags) {
krk_defineNative(&vm.globals, "dir", krk_dirObject);
krk_defineNative(&vm.globals, "len", _len);
krk_defineNative(&vm.globals, "repr", _repr);
krk_defineNative(&vm.globals, "print", _print);
/* __builtins__.set_tracing is namespaced */
krk_defineNative(&vm.builtins->fields, "set_tracing", krk_set_tracing);
@ -2735,23 +2783,6 @@ static KrkValue run() {
int operandWidth = (opcode & (1 << 7)) ? 3 : 1;
switch (opcode) {
case OP_PRINT_LONG:
case OP_PRINT: {
uint32_t args = readBytes(frame, operandWidth);
for (uint32_t i = 0; i < args; ++i) {
KrkValue printable = krk_peek(args-i-1);
if (IS_STRING(printable)) { /* krk_printValue runs repr */
fprintf(stdout, "%s", AS_CSTRING(printable));
} else {
krk_printValue(stdout, printable);
}
fputc((i == args - 1) ? '\n' : ' ', stdout);
}
for (uint32_t i = 0; i < args; ++i) {
krk_pop();
}
break;
}
case OP_RETURN: {
KrkValue result = krk_pop();
closeUpvalues(frame->slots);