Glass
- This is a featured language.
Glass is an esoteric programming language developed by Gregor Richards in 2005. It combines an unintuitive postfix notation with heavy object-orientation, requiring extensive juggling of a main stack combined with its object-oriented structure. No other language that the author knows of is implemented like this, because it would be idiotic.
Contents |
[edit] Syntax
The language is parsed into distinctive elements, each one character long, with the exception of these groupings:
(name)or(number)is parsed as a single variable name or stack reference number."string"is parsed as a string value.<number>is parsed as a numeric value (integer or floating-point).'comment'isn't parsed at all, it's a comment (non-nestable).
Parentheses () are optional around a single letter A-Z, a-z or digit 0-9. Therefore, the variable name a could be represented by both a and (a), but the name abc could only be represented as (abc).
A program consists of a sequence of class definitions.
Each class definition has the form
{class-name function-definitions}
The class-name must be the name of a global variable which becomes a reference to the class.
A function definition has the form
[function-name content]
The function-name must be the name of a class-local variable which becomes a reference to the function. The content is an arbitrary sequence of commands.
For example:
{M[m...]}
would declare a class M with a function named m which does ...
{(Main)[(main)...]}
would declare a class Main with a function named main which does ...
[edit] Execution
Execution starts by creating an instance of the class M and running the function M.m. That is, it is equivalent to the following sequence of commands:
(_t)M!(_t)m.?
[edit] Variables
There are four types of variables, partly separated by the format of their name:
- Global variables, with names beginning with upper-case characters.
- Variables local to a class, with names beginning with lower-case characters. These are immutable and must be looked up with the . command rather than the * command.
- Variables local to an object, with names beginning with lower-case characters.
- Variables local to the current invocation of a function, with names beginning with an underscore. (Note that names beginning with an underscore must be parenthesized.)
Variable names are only resolved in the context where they are actually used - that is, if you introduce the name _a in function a, and pass it back to the parent function, which uses the returned name, it will not refer to the variable _a of function a, but to the _a of the parent function. Autogenerated global variables are available to alleviate this issue. The contextual-ness of variable names is also why the . operator (seen later) works even though you push the name of a class-local variable - it resolves that variable in the context of the called class, not the caller.
[edit] Commands
Each command is listed in this form:
- command : stack before — stack afterwards
- description
In this notation (due to Forth), stack elements are separated by spaces, and the top of the stack (i.e. the most recently-pushed element) is listed last.
[edit] Command list
(name): — name- Push a variable name onto the stack.
- If name is a single letter from a-z, A-Z, then the parentheses are optional.
(number): snumber ... s1 s0 — snumber ... s1 s0 snumber- Duplicate an element number positions down the stack to the top of the stack.
- If number is a single digit 0-9, then the parentheses are optional.
"string": — string- Push the string onto the stack.
<number>: — number- Push the number onto the stack.
,: value —- Pop a value from the stack.
^: —- Return (from function).
=: name value —- Assign value to variable name. For composite values, only references are copied.
!: name cname —- Assign a new instance of the class in variable cname to the variable name. Pop the names from the stack, then run the c__ (constructor) function of the newly instantiated object.
.: oname fname — function- Retrieve the function fname defined in the class of the object oname. The object becomes the current object of the retrieved function.
- The variable oname is looked up in the current context, while fname is looked up in the context of the class of the object.
?: stack-before function — stack-afterwards- Pop the function from the stack, then run it. The effect on the stack depends on the function.
*: name — value- Retrieve the value of variable name (in the current context).
$: name —- Assign the current object to variable name.
/(name)commands\: stack-before — stack-afterwards- Repeat commands while the variable name has a "true" value. The effect on the stack depends on content.
- Values are considered "true" if they are non-zero numbers or non-empty strings.
As an example of using commands, here is a segment of code to instantiate a class O into the variable _o, then run the function _o.o with "Hello World!" on the stack:
(_o)O!"Hello World!"(_o)o.?
So, to make a hello world program (assuming that the O class is built in to the system), do the following:
{M[m(_o)O!"Hello World!"(_o)o.?]}
Isn't that easy?!
[edit] Special definable functions
- c__
- Constructor function of a class, run whenever an object is created.
- d__
- Destructor function of a class, run when an object is garbage collected.
- m
- Function in class M, run to execute the whole program.
[edit] Built-in classes
Each built-in function is listed in the form
- Class.function : stack before — stack afterwards
- description
Note that Class.function is not legal Glass syntax for using the function, you need to do something like
(_C)Class!(_C)function.?
[edit] Class A (Arithmetic)
- A.a : x y — x+y
- Addition
- A.s : x y — x-y
- Subtraction
- A.m : x y — x*y
- Multiplication
- A.d : x y — x/y
- Division
- A.mod : x y — (x mod y)
- Modulus
- A.f : x — floor(x)
- Floor
- A.e : x y — x==y
- Equality
- A.ne : x y — x!=y
- Inequality
- A.lt : x y — x<y
- Less than
- A.le : x y — x<=y
- Less than or equal to
- A.gt : x y — x>y
- Greater than
- A.ge : x y — x>=y
- Greater than or equal to
[edit] Class S (Strings)
- S.l : string — length
- Retrieve the length of string.
- S.i : string n — character
- Retrieve the nth character of string.
- S.si : string n char — newstring
- Replace the nth character of string with char.
- S.a : s1 s2 — s1s2
- Concatenate strings.
- S.d : string pos — s1 s2
- divide string at point pos, s1 is the first part, s2 is the second.
- S.e : s1 s2 — s1==s2
- String equality.
- S.ns : number — character
- Convert a number to a character.
- S.sn : character — number
- Convert a character to a number.
[edit] Class V (autogenerated Variables)
- V.n : — newname
- Push name of a new global variable.
- V.d : name —
- Delete an autogenerated variable.
[edit] Class O (Output)
- O.o : string/name —
- Output string or name.
- O.on : number —
- Output number.
[edit] Class I (Input)
- I.l : — string
- Retrieve a line of input.
- I.c : — char
- Retrieve a character from input.
- I.e : — is-eof
- Push 1 if end of input, 0 otherwise.
[edit] Examples
[edit] Hello, world! program
{M[m(_o)O!"Hello World!"(_o)o.?]}
[edit] Fibonacci sequence
{F[f(_a)A!(_o)O!(_t)$(_n)1=,(_isle)(_n)*<2>(_a)(le).?=/(_isle)<1>^\(_n)*<1>(_a)
s.?(_t)f.?(_n)*<2>(_a)s.?(_t)f.?(_a)a.?]}{M[m(_a)A!(_f)F!(_o)O!(_n)<1>=(_nlm)
<1>=/(_nlm)(_n)*(_f)f.?(_o)(on).?" "(_o)o.?(_n)(_n)*<1>(_a)a.?=(_nlm)(_n)*<20>
(_a)(le).?=\]}
[edit] Randomizer class
{(Rand)[(c__)s<5>=][(rand)(_a)A!ss*<1103515245>(_a)m.?<4294967295>(_a)(mod).?
<12345>(_a)a.?=s*<65535>(_a)d.?<32768>(_a)(mod).?][(seed)s1=,][(randi)(_a)A!
(_t)$(_min)2=(_max)1=,,(_min)*(_max)*(_min)*(_a)s.?<1>(_a)a.?(_t)(rand).?(_a)m.
?<32768>(_a)d.?(_a)a.?(_a)f.?]}
[edit] Quine
{M[m(_s)S!(_o)0O!o.<34>(_s)(ns).?"{M[m(_s)S!(_o)0O!o.<34>(_s)(ns).?"
"14?24?14?24?24?04?24?04?]}"14?24?14?24?24?04?24?04?]}
[edit] Cat
{M[maI!bO!cA!dae.?<1>c(ne).?=/dac.?bo.?dae.?<1>c(ne).?=\]}
[edit] 99 bottles of beer
{B[b<99>^]}{P[(c__)oO!t$aA!][n<10>s(ns).?oo.?][poo.?tn.?][b(_m)1=,(_x)<0>
(_m)*ae.?=(_y)<1>=/(_x)"No more"oo.?(_x)0=(_y)0=\/(_y)(_m)*o(on).?(_y)0=\
" bottle"oo.?(_x)<1>(_m)*ae.?=/(_x)^(_x)0=\"s"oo.?]}{C[(c__)oO!aA!sS!pP!t
$][gn*][xn1=,][dnn*<1>as.?=][vn*pb.?" of beer on the wall,\n"pp.?n*pb.?qe
" of beer,\n"pp.?"Take one down, pass it around\n"pp.?ln*<1>as.?=l*pb.?wu
" of beer on the wall.\n\n"pp.?pn.?]}{M[moO!cC!bB!bb.?cx.?fcg.?=/fcv.?cd.
?fcg.?=\]}