Example
Remember that there are many examples in the demo directory and a
syntax highlighting definition file for Kate in the doc directory.
This is the famous Hello World program excessively written in Qu.
We could just say:
print ('Hello World!')
but that wont be fun. Besides, the following example does tell you some
things about Qu.
use Time
println (Time.web)
hello
sub hello (msg = nil)
```
Prints a message for the world.
```
local head = false
do try
msg is String or throw EValue, "me want string"
msg.('l' _ 'en') or throw EValue
print (msg.capitalize)
head = true
catch EValue
msg = `hello`
redo
finally
assert (head is true, "eh?")
println (' World!')
;;
;;
And here is a "simpler" one showing you the power of validators.
hello ('world!')
sub Message (x)
return x is String and x and not x.isspace ? x.capitalize : false
;;
sub hello (s: Message)
println ('Hello ', s)
end sub
var name: String.isalpha
var path: File.isabs
enum Level
LOW
MEDIUM
HIGH
;;
struct Person
name : String
age : Integer
pals : Array of Person
;;
sub foo (x: Person) -> Level
...
;;
const Picky = 1..10
const Weird = const [1, 2, 7, 9]
var foo: Picky
sub foo (x: Picky) -> Weird
...
;;
Here are some examples of Qu's flexible syntaxes.
println (x) if y > 10
println (x) for x in 1, 20
x = [for i in 1, 2: [for j in i, i + 2: i + j]]
x = [while i--: i if i & 1]
s = {for c in 'abcde': c == 'd' ? break : c}
f = sub (x) return x.len > 3 ;;
f = lambda (x) x.len > 3
f = {|x| x.len > 3}
f = {|x| yield i for i in x}
a.sort (sub (x, y) return x <=> y ;;)
a.sort (lambda (x, y) x <=> y)
a.sort ({|x y| x <=> y})
Qu has an "experimental" feature that allows you to override or extend
functions of any module and even methods of any class, provided that you
do it from a trusted module. Extremely abusive but very useful in
some situations.
sub Sys.print (*arg)
Stream.stdout <<< x for x in arg
;;
sub String.notempty
return self.len > 0
;;
sub class File.nicepath (x)
return File.valid (x) and ' ' not in x
;;
var path: File.nicepath
use Sys
sub Sys.println (*arg)
static linecount = 0
Stream.stdout <<< ++linecount <<< ': '
Stream.stdout <<< x for x in arg
Stream.stdout <<< Stream.stdout.linebreak
;;
Stream.stdout.linebreak = ' :-)\n'
println ('Hello')
println ('World')
Qu provides convenient ways to communicate with C.
The Dlib class provides access to shared libraries.
The Proc class makes it possible for C functions to call Qu functions.
The Pointer class provides an easy way to deal with C structs.
local handler = Proc (@foo, 2)
sub foo (a:_int_, b:_float_, c:_String_, d:_double_) -> _String_
println ('self = ' self)
println ('a = ', a)
println ('b = ', b)
println ('c = ', c)
println ('d = ', d)
return 'Hello from Qu'
;;
l = Dlib ('/opt/qu/lib/Qu.so')
l.call ('QuSetIt', '-:P', handler)
l.call ('QuCallIt')
struct Foo
thing : _int_
thang : _float_
;;
p = Pointer (Foo)
p->thing = 1
p->thang = 2.3
Here is an example using the indentation style ala Python.
The difference is that you must only use tabs.
The pragma statement must be the first statement in the file.
Once specified, it means you are using indentation style for the whole file.
The line continuation token is a triple dot.
hello ('Hello')
sub hello (s)
if s
for c in s
print (c)
println (' World!')
else
__exit__ (1)
a = b + ...
c + d
Did you know you can embed HTML code directly in your Qu program?
Here's an example.
pragma html
options = [foo:1, bar:2, baz:3]
<FORM ACTION="/foo" METHOD="POST">
<SELECT NAME="choice">
for k, v in options
<OPTION VALUE=v>(\k)</OPTION>
;;
<INPUT TYPE="submit" VALUE="Send">
</SELECT>
</FORM>
And finally a glance at Qu's object oriented style.
This is not the whole story, of course. And remember that in Qu using object oriented
programming is just a matter of choice.
use Foo
use FooEdit
use FooDisplay
class Bar is Foo (FooEdit.FooEditStandard, FooDisplay) __final
const ValidAge = 1..200
var class flag = 1
var name := ''
ensure
return name is String
and name.len in 1..40
and not name.isspace
;;
var nice = true
var age: ValidAge
sub __init (name, age, nice = true)
self.name = name
self.age = age
self.nice = nice if nice
;;
sub class setflag (x: Int) -> Null
flag = x
;;
sub say (x)
static v = const ['bad', 'nice']
println (v [Int (self.nice)] ': ' x)
;;
sub __print
print ('I am a ' self.__name)
;;
sub Nice
return self.nice
;;
;;
var Her: Foo.Nice
|