-
-
Save amcgregor/e4114c3f3f1b71e543fb to your computer and use it in GitHub Desktop.
Additional Clueless code samples and ideas.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/env q | |
# encoding: utf-8 | |
# account.q | |
class Account # Account = Object.clone.with | |
balance = 0 | |
method deposit(value) | |
self.balance += value | |
method withdraw(value) | |
self.balance -= value | |
method show | |
print("Account balance: $", self.balance) | |
myAccount = Account.new | |
myAccount.show | |
print("Depositing $10") | |
myAccount.deposit(10) | |
myAccount.show | |
variables: | |
this: the current context; variable lookups start here | |
object..parent: the class (or multiclass; i.e. object) this one inherits from | |
this..parent: the next variable context up, not always the next caller up | |
this.. | |
macro 'integer' name | |
pass | |
macro 'integer' expr | |
pass | |
macro 'def' name . '(' . [ expr, ] . '):' ... | |
fn = this..child | |
ctx = this..parent | |
fn.this..parent = ctx | |
fn.this..update(ctx..eval(*expr)) | |
ctx[name] = fn | |
# encoding: utf-8 | |
define routine | |
pass | |
define somefunc with argument1, argument2=None, argument3=None | |
pass | |
define otherfunc with | |
integer argument1 = 24 | |
string argument2 = 'hello' | |
float argument3 = 3.141 | |
pass | |
# typecasting | |
xyzzy = 1 as float # (1).asFloat | |
yzzyx = "foo" as string # ("foo").asString -- this is double-quoted text, not a raw bytestring | |
built-ins | |
from org.q.core import __debug__ | |
# these is a magical and built-in macros (classically 'statements') | |
macro # transparent function call that integrates with the parser | |
replace # compile-time replacements | |
'pass' | |
'return' expr | |
'yield' expr | |
'raise' expr | |
'continue' # stop execution of the current code block | |
'import' module ["as" name] | |
'from' module 'import' name ["as" name] | |
'global' name # assignments to this name within the current scope assign to the parent | |
'try' | |
'except' name [ 'as' name ] | |
else | |
replace 'except' | |
except Exception | |
replace 'return' expr | |
raise Success(expr) | |
replace 'return' | |
return None | |
replace 'yield' | |
yield None | |
replace 'raise' | |
raise Exception | |
macro name '=' expr | |
this..parent..set(name, this..parent..eval(expr)) | |
replace 'forget' name | |
this..unset(name) | |
replace 'delete' name | |
this..parentOwning(name).unset(name) | |
macro 'not' expr | |
return this..parent..eval(expr).asBoolean.inverse | |
_if = macro 'if' expr ... | |
this.parent..result = this.parent.eval(expr).asBoolean.ifTrue(this.child) | |
macro [_if] 'else if' expr ... | |
if this.parent..result | |
return | |
this.parent..result = this.parent.eval(expr).asBoolean.ifTrue(this.parent) | |
macro [_if] 'else' ... | |
if this.parent..result | |
return | |
this.child.withContext(this.parent)() | |
macro 'assert' expr | |
if not this..parent..eval(expr) | |
raise AssertionError | |
macro 'assert' expr . ',' expr | |
if not this..parent..eval(expr.0) | |
raise AssertionError(this..parent..eval(expr.1)) | |
replace 'break' | |
raise StopIteration | |
_while = macro 'while' expr ... | |
try | |
forever | |
if not this..parent..eval(expr) | |
raise StopIteration | |
this..parent..result = True | |
this..parent..eval(this..child) | |
except StopIteration | |
pass | |
macro [_while] 'else' ... | |
if this.parent..result | |
return | |
this..parent..eval(this..child) | |
_for = macro 'for' name 'in' expr ... | |
iterator = this..parent..eval(expr).asIterator | |
try | |
forever | |
this..child..this[name] = iterator.next | |
this..parent..result = True | |
this..parent..eval(this..child) | |
except StopIteration | |
iterator.close | |
macro [_for] 'else' ... | |
if this.parent..result | |
return | |
this.child | |
macro 'for' name 'in' expr ... | |
iterator = this..parent..eval(expr).asIterator | |
try | |
forever | |
this..child..set(name, iterator.next) | |
this..parent..eval(this..child) | |
except StopIteration | |
pass | |
for foo in 'bob' | |
print(foo) | |
define Object:.| attr | |
return self[attr] | |
define Object:..| attr | |
return self['_meta'][attr] | |
define Object:with ... | |
this.child.context = self | |
this.child() | |
macro 'with' expr ['as' name] ... | |
# First, evaluate the expression in the calling context. | |
obj = this.parent.eval(expr) | |
if obj.contains('enter') | |
obj.enter | |
exit = obj.get('exit', nil) | |
# If we don't want the variable to persist beyond the with block, change this to 'this.child.context'. | |
if this.context.contains('name') | |
this.parent.context[name] = obj | |
try | |
this.child | |
except | |
if exit and exit(this.exception) | |
raise | |
if exit: | |
exit | |
class Error | |
method init(message) | |
self.message = message.asText | |
method asString | |
return self..name + ': ' self.message | |
class NumericError: Error | |
method init(code, message) | |
self.code = code.asInteger | |
this.parents(message) | |
method asString | |
return self..name + ' (' + self.code + ') ' + self.message | |
class SliceError: Error | |
pass | |
class StopIteration: Error | |
pass | |
class Range | |
# Defines a for-loop style range iterator. | |
# You can natively loop over this object; each time it is looped over it resets its position. | |
method init(start=0, end=0, each=1) | |
self.start = start | |
self.end = end | |
self.each = each | |
self.i = nil | |
method asIterator | |
return self.copy | |
method enter | |
self.i = self.start | |
method next | |
value = self.i | |
if value > self.end | |
raise StopIteration | |
self.i += self.each | |
return value | |
List.with | |
method isEmpty | |
return self.length.asBoolean | |
method first | |
return self[0] | |
method last | |
return self[-1] | |
method slice(range) | |
if not range.implements(Range) | |
raise SliceError("Invalid range: " + range) | |
result = List.new() | |
for element in range | |
result.append(self[element]) | |
return result | |
Generic Meta Attributes | |
parent | |
get(name[, default]) | |
set(name, value) | |
eval(code) | |
Function Meta Attributes | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment