ATALAN Programming Language Reference

Atalan source code is ASCII text file. It does not support reading of UTF-8 files, it can however safely skip UTF-8 header, so if you mistakenly safe your source code using UTF-8 (hello PSPad), there should be no problem.

Atalan is case insensitive.

Syntax elements

Literals

Numeric and string literals may be defined.

65535 dec $494949 hex %0101010 bin "C" character string

It is possible to separate parts on a numeric constant by apostrophe.

65'535 $ff'ff %0101'0101'0101'1111

Comments

Anything after ; is comment.

Indent

Indent may be used to define blocks of code for control structures.

Identifiers

Identifiers must start with letter and may contain numbers, underline and apostrophes. Identifier may be enclosed in apostrophes. In such case, it may contain any characters including apostrophe.

Example: name x1 x2 x'pos 'RH-' 'else' ; this is identifier, even if else is keyword

Variables, types, constants and assignment

Variables do not have to be defined, they are declared using assignment action.

name ["@" adr] ["," name]* [":" [min ".." max]|[var] [ "(" dim ["," dim2] ")" ] ["=" value ["," value]

name Name of variable, multiple variables may be declared/assigned (separated by comma) adr Place variable at specified address or register.

Type is declared using one of following methods:

Type declaration

Type is defined using 'type' keyword.

type short:-128..127 ; signed byte type type byte:0..255 type word:0..65535 type int:-32768..32767 type long:0..$ffffff type char:byte

Const declaration

Constant is variable, that is initialized during declaration and never assigned again. Array may be used as const to define static data.

const TAB = 3 * 3 ; it is possible to use expressions to evaluate constants const SPC = 32 const DIGITS:char(16) = "0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"

Const keyword introduces a block, so it is possible to declare multiple constants at once.

const TOP = 1 BOTTOM = 2

Register declaration

It is possible to place variable to specified address. This is usually used to define system and hardware registers. PCOLR @704:byte(4) ; player & missile graphics color (4 missiles) COLOR @708:byte(5) ; playfield color SDLSTL @560:ptr ; pointer to beginning of display list STICK @632:byte(4) Value of some hardware registers changes automatically. It is necessary to mark such variables as 'in' or 'out'.

Variable assignment

x = y

Multiple assignments

x,y:int x,y = 3,4 x,y = y,x [TODO] x,y = cursor

Writing to specified address [TODO]

Anonymous variable may be assigned (like POKE in BASIC). It is possible to specify type too.

@712 = 0 ; set background color to black @$230:ptr = my_dlist @buf:byte(100) = 0 ; set 100 bytes at address stored in variable buf to 0 (memset)

Labels

Label is specified as variable located at address where address is not specified. Note, that there must be at least one space after label definition.

name@

Integers

Integer type is declared using numeric range. Compiler automatically decides, how many bytes to use.

byte:0..255 word:0..$ffff int:-32768..32767 flag:0..1

Associated constants

It is possible to associate constant with integer type. Associated constant works like enum, but the type remains integer (i.e. you can still assign numbers to them).

color:0..255 const gray:color = 0 const pink:color = 4

When using associated constant, it must be preceded by type name and dot. It is not necessary, when the type is clear (assigning or comparing with variable of the )

c1:0..255 c2:color c1 = color.gray c2 = pink ; c2 is of type color, color. is not necessary

Enums

Enumerators are integer types, that define list of named values, that may be assign to them.

Enums are declared using enum keyword optionally followed by numeric range. If numeric range is specified, all constants associated with this enum must be in the range. If not specified, range is computed automatically based on specified values.

button_state:enum (pressed = 0, not'pressed = 1) color: enum gray pink purple

Structures [TODO]

Structure is defined as list of variable declarations. Either "," or new line may be used as separator.

xcoord:0..319 ycoord:0..239 point:(x:xcoord, y:ycoord) point: x:xcoord ; x screen coordinate y:ycoord ; y screen coordinate

Using @ inside structure places the variable at specified offset from the beginning of a structure. Structures with 'holes' can be defined this way, even if it is not usually very useful.

audch: f:byte ; frequency c:byte ; control aud@$D200:audch(4)

Arrays

Array is defined using keyword array.

name:array [(min..max|count)[,(min..max|count)]] of byte

If the array size is defined using single value, the value defines maximal index. Minimal index is then 0. So x:array(31) defines array of 32 elements (index 0..31).

Array can be defined as one or two dimensional.

Initialization

It is possible to initialize arrays using literals. Array constants are defined as comma separated list of values. It is not necessary to define dimension for initialized array.

If there is reference to array variable as part of array initializers, pointer to that array is stored in the array. This is possible for byte arrays too, in such case the element will occupy multiple bytes (usually 2 bytes for 8-bit processors).

When some item is to be repeated several times in initialization, it is posible to use <n> TIMES <item> construct. <n> must be integer number. If it is lower or equal 0, no item will be generated.

disp:array(0..39,0..23) of byte const a:array of byte = 3 times 112, disp, 0 ;Array has dimension 0..6

Element access

Array element is accessed using parentheses.

arr:array(10) of byte arr(1) = arr(2) scr:array(39,23) of byte arr(0,0) = 65

Range access [TODO]

When assigning single variable to array, all items in array are set.

screen:array(39,239) of byte screen = 0 ; clear the screen (fill with 0)

Operators

* / Multiplication, division + - Addition, substraction lo hi Low/high byte of a word (lo $abcd = $ab, hi $abcd = $ab) and or Bit operators xor not Bit operators [TODO] ( ) Parentheses

Conditions

Expression used in conditions have slightly different rules than normal expressions. They (at least in theory) evaluate to true/false. If simple value is used, it's 0 value means false, any other value true.

not Logical negation and or Logical operators with short circuit evaluation = <> < > <= >= Relational operators [TODO: == and <> working] is isn't Same as '=' '<>' (lower priority). [TODO]

Commands

Printing

String constant used as command will be printed to screen.

"Hello, World!" "" "I'm here!"

Square braces may be used to insert variables into the printed string.

x = 4 y = 6 z = x + y "Sum of [x] and [y] is [z]."

Variable type is automatically recognized, there is no need to specify it.

Control structures

Labels & Jumps

Label is be defined as

label@

It is possible to jump on specified label unconditionally using goto.

goto label

It is also possible to jump to address specified in variable.

x:word x = 1000 goto x ; jump to address 1000

Blocks

Control structures organize code in blocks. Block is list of commands.

Block may be defined using several methods:

Conditional execution

Full conditional statement is supported. Note, that the blocks may be defined using indent. It is possible to optionally use THEN keyword after condition. Arbitrary number of else if sections is supported.

if <cond> [then] <code> else if <cond2> <code> else <code>

Short one-line version is supported. if <cond> then <code>

Again, it is not necessary to use then: if <cond> goto <label>

Loops

Repeat commands in the block as long as the specified condition is true. while <cond> <block>

Repeat commands in the block as long as the specified condition is not true. until <cond> <block>

Loop iterating over variable. for <var> <body>

The variable must be integer. All possible values will be iterated, depending on variable type. The variable must be defined in advance, after the end of loop, it will contain last processed index.

It is possible to specify condition for loop using where keyword. for <var> where <filter> <body> Loop body is executed only if the condition after where is true.

It is possible to combine the loops. Following code will write numbers between 1 and 10000, until end is reached of Q key is pressed.

for k:1..10000 until CHAR1 = Q "[k]"

Procedures

Procedures can be defined using proc type. After the proc keyword follows block defining procedure arguments. Arguments marked using "<" are output arguments ( results).

name ":" "proc" args = code addw:proc i:word j:word >k:word = k = i + j add3: word proc i:word j:word k:word >result:word = result = i + j + k

Multiple results

Procedure may define more than one output arguments (results).

sumdiv:proc a,b:byte >sum:byte >div:byte = sum = a + b div = a - b a:byte b:byte a,b = sumdiv 10 3 "Sum is [a], div is [b]"

Nested procedures

It is possible to define local procedure inside other procedure.

set'line'color:proc = wait'line:proc = WSYNC = 0 COL'BK = VCOUNT * 2 + RTCLOCK wait'line

Procedures with identical signatures

Procedure may be declared using type of another procedure.

subw:addw = k = i - j

Procedures at specified address

It is possible to define routines in ROM using @ syntax.

reset@$E034:proc