Skip to content

Instantly share code, notes, and snippets.

@vird
Created May 25, 2012 14:43
Show Gist options
  • Save vird/2788495 to your computer and use it in GitHub Desktop.
Save vird/2788495 to your computer and use it in GitHub Desktop.

ZIRCON (Vird edition)

General language features

Requiring another file

use :base # .zr is assumed
use :base, :extensions, :extensions-optional # if no file is found, but folder is present, loads all .zr files from the folder
use-all # loads all .zr files in current folder
use "core/base.zr" # direct filename

Scope

if a==1
    # this is 4 spaced intendation

if a==1
{
    # this is scope limited by {}
}
if a == 1 {b=3} #just another case of scope
if a == 1 {b=3;c=3} #dotcomma saparates operations in single line

constants

Constants is case insensitive

true == True # actually same
true == TRUE # actually same
FalsE== FaLsE# warning: nonrecommended constant usage
Nan  == NAN  # actually false due float compare logic

Constants is very flexible

123456789
123_456_789 # equal to 123456789
123 456 789 # equal to 123456789

123456789i # defining imaginary part of complex number 
# oct/hex
256
0400 # oct numbers begin from '0'
0xFF # hex numbers begin from '0x' or 'OX'
0XFF
#float
#2. banned format!
2.0
2.12321321
# exponential form
2.12321321e+01
2.12321321E+01
2.12321321E+1 # leading zeros in exp can be omitted
2.12321321E1 # + in exp can be omitted
2.12321321E1i # now it's imaginary

control flow

if

if expr
   #if expr == true


if expr
   #if expr == true
else
   #otherwise


if expr
   #if expr == true
elseif expr
   #if expr == true
else if expr
   #if expr == true
elif expr
   #if expr == true
else
   #optional

# inlined
a=5 if b==1

switch

case expr
    1 ? #space strongly is required
    2 ? #break is automatically added by default
    '1' ? 
    1..10 ? #range is valid value
    1,2,3 ? #list is valid value
	:else ? #

#experimental
case expr manual_nreak
    1 ? #here break is not automatically added by default
    2 ? #all this cases will execute from start line up to end line
    '1' ? break #but here we dropped
	:else ? #

while

while expr
    # body

do
    # body
while expr

loop #equivalent to while true
    # body

for range

for i in 1..10
	# body

for classic (experimental)

for(i=0;i<n;i++)
	# body

for each constructor

fore_kv arr k v
	# k - key
	# v - value
fore_vk arr k v
	# v - key
	# k - value
fore_cv arr k v
	# k - ordinal number
	# v - value
fore_ckv arr c k v
	# c - ordinal number
	# v - key
	# v - value

for/for each cycle management

for i in 1..10
	next # cycle increment and go to begin
	continue # synonym to next
	break # exit cycle
	prev # cycle decrement and go to begin
	retry # go to begin and no cycle increment
	# php-styled modifications
	break 2 # exit from 2 cycles
	next  2 # exit from 1 cycle and continue from new current cycle
	# iterator manipulations
	retry +2 # increment+2 and retry
	retry -2 # increment+2 and retry
	move +2 # increment+2
	move -2 # increment+2
	retry rewind   # move pointer to begin and retry
	rewind # move pointer to begin but continue from next line

basic operations

Variable assigning

a = b
a, b = b, a # swapping
a, b, c = d, e, f # mass assignment
first, second, third = a # list decomposed into elements
a = :first, :second, :third # a is a list

Get the type of variable

a = 2.14
type a #=> :float
typeof a #=> :float
float? a #=> true. type? function is defined for every type and struct, including user-defined

“Or equals”

a = 5 if foo
a ?= 3 # if a is not set, 3, else, no change

logic operations

a &&= b && c
a and= b and c
a ||= b || c
a or= b or c
a ^^= b ^^ c
a xor= b xor c
a = !a
a = not a

in fact in most cases there is no difference between logic and logic operations

a &= b & c
a and= b and c
a |= b | c
a or= b or c
a ^= b ^ c
a xor= b xor c
a <<= b >> c
a = ^a # Go lang syntax
a = not a

math operations

a += b + c
a -= b - c
a *= b * c
a /= b / c
a %= b % c # modulo
a **= b ** c # power
a--
a++
--a
++a
a = -a
# yep you can still write in c++ style

Special math functions (experimental)

ln a
ln2 a
log2 a # equal to ln2
exp a # equal e ** a
# in fact you can use "method call" operations
a.ln, a.ln2, a.exp
# but there is no postfix operation aliases due bad formula readability
a ln # is invalid

basic types

string

String interpolation

apples = '33 tasty apples'
oranges = '6 juicy oranges'
output = "I had $apples and $oranges" # note double quotes
output = "I paid \$34 for them" # uninterpolated dollar sign
output = 'I paid $34 for them' # WILL NOT WORK similar to PHP
output = "I paid #{34} for them" # ruby compatibility
#special chars
output = "\a\e\b\f\n\r\t\v" # escape sequence with char
output = "\'\"\\" # other escapes

output = "\007" # octal escape sequence
output = "\xfF" # hex escape sequence case incensitive
output = "\u12e4" # unicode escape sequence
output = "\U00101234" # another unicode escape sequence
# special constant policy for single quotes and single char
char = 'a' # this is not string but char type! In fact can be used as string anywhere, but string can't be used as char
char = "a" # this is string
char = 'aa' # this is also string
char = '\n' # this is char! escape sequence works
char = '\n\n' # here escape sequence also

Convert anything to string

a = 5
`a #=> '5'
`5 #=> '5'
a to_s # another way

struct name = :first-name, :last-name

john-smith = *name 'john' 'smith'

`john-smith #=> "first-name:john, last-name:smith" - default to_s for structs

f `name
    f, l = (first-name, last-name) @@ capitalize
    "$f $l"

`john-smith #=> "John Smith"

some methods

a='123'
strlen a # strlen as function
a.length # length as method
a length # length as postfix operation
a count # count as postfix operation. return 3
a size # count as postfix operation
# most methods have their postfix operations aliases

array

Different array initialization methods

apples = 1,2,3
apples =
    1
    2
    3

apples =
    1,
    2,
    3

apples = [
    1,
    2,
    3
]

apples = [
    1
    2
    3
]
apples = [1,2,3]

some methods

apples = [1,2,3]
apples count # count as postfix operation. returns 3
count apples # count as function. returns 3

hashes

hash = field: 'a', other-field: 'b', yet-another: 'c' # :field, :other-field and :yet-another are symbols
var = :new-var
hash << ($var: 'd') # hash :new-var == 'd'
hash.$var = 'd' # alternative
hash.field # => a

struct

struct phone-number = :area-code, :number
larrys-number = *phone-number # * is new prefix operator
larrys-number = new phone-number # this syntax is also valid
larrys-number.area-code = 303
larrys-number.number = 5053819

function

definition

f do-stuff arg1, arg2
    do-more-complex-stuff arg1, arg2, 5 # Basic function declaration

f inline-function = 'Hello world' # one-line version

f zircon? (arg1, arg2='zircon') = true if arg1 == arg2 # default parameters defined only when () is used

f zircon? arg1, (arg2,'zircon') = true if arg1 == arg2 # another way default parameters

# Warning: for every struct defined, struct-name? is reserved.

# Types of functions are normally inferred. Manual type declaration:

f real-part x :complex
    x.real

f real-part-equal? x:complex, y:numeric
    x.real == y

# Full type signature

f imaginary-part-equal? x:complex, y:numeric -> boolean
    x.imaginary == y

Return values

f add x, y 
    x + y #=> last statement is returned by default

f divide x, y
    return NAN if y == 0 #=> preemptive return
    x / y

f add x:complex, y :numeric # space between variable name and type is possible
    y-real, y-imaginary = complex? y ? (y.real, y.imaginary) : (y, 0)
    *complex x.real + y-real, x.imaginary + y-imaginary #=> struct is returned


f add x:complex, y:numeric :complex # strict return type. You can't define return variable type but not define type of last argument
    y-real, y-imaginary = complex? y ? (y.real, y.imaginary) : (y, 0)
    *complex x.real + y-real, x.imaginary + y-imaginary
f add x, y -> :complex # You can define return variable type but not define type of last argument. Just add ->. -> is optional
    y-real, y-imaginary = complex? y ? (y.real, y.imaginary) : (y, 0)
    *complex x.real + y-real, x.imaginary + y-imaginary

pseudoOOP (no inheritance)

struct phone-number
    :area-code
    :number
    f method arg
        @number = 1 # @ is #this-> operator
    static :s_var
    static f s_method arg
        self:s_var = 1
larrys-number = *phone-number
larrys-number.area-code = 303
larrys-number.method # this is method call
phone-number.s_method # this is static method call

Exceptions

f check-twitter username
    stream = open "http://twitter.com/$username" # http/ftp streams, files can used as argument
    err :no-connection unless stream
    err :twitter-troubles if err? stream
    stream

f twitter-status
     true unless err? check-twitter 'zircon'

# Exception handling
try
    #code
catch
    #code

try
    #code
catch exception_variable
    #code


try
    #code
catch exception_variable :expression_type1 
    #code
catch exception_variable :expression_type2
    #code


try
    #code
catch exception_variable :expression_type1 
    #code
catch exception_variable :expression_type2
    #code
catch exception_variable
    #code

try
    #code
catch :expression_type
    #code

Other features

Testing

f multiply x, y
    inlinetest 5, 2 -> 10 # multiply 5, 2 should be equal to 10
    inlinetest 8, x -> (x << 3) # basic support for fuzzing
    inlinetest 133, 14 -> 1862
    inlinetest x * y

Map reduce

array = 1,2,3
array2 = array @@ to_s # map
array2 = array map to_s # map


array = 1,2,3
p array >> sum # reduce. prints 6
p array reduce sum # reduce. prints 6

Join an array

a = 3, 5, 9
`a #=> "3, 5, 9" - default to_s for lists
`a ' - ' #=> "3 - 5 - 9" - an argument specifies join string

Namespaces

Usage

use :animals-core #=> loads animals-core.zr, no namespace defined
use :pigs, Pig #=> define Pig namespace for functions in pigs.zr

Pig:oink #=> a function called which is defined in pigs.zr

f oink
    'Oink!'

p oink #=> local implementation
p Pig:oink #=> external implementation

Definition

namespace Pig
    f oink
        'Oink!'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment