စံကား

01The language

Expressions

Literals, names and the operators in each group - arithmetic, comparison, logic and bitwise - with precedence, division, overflow and grouping.

An expression is a piece of program that has a value. It can be a literal, a name, or operators applied to other expressions. Most operators have two spellings that mean the same, a sign (+) and a Burmese phrase (နှင့် ... ၏ ပေါင်းလဒ်), and the two can be mixed in one expression. The compiler works out the kind of each expression before the program runs (Kinds and values).

Three tiers

The grammar of an expression has three tiers, from the tightest to the loosest:

notation   က + ခ * ၂       -ဂ        (က - ခ)         signs, prefix signs, parentheses
clause     က နှင့် ခ ၏ ပေါင်းလဒ်     က သည် ခ ထက် ကြီး     operands with particles, closed with a verb
logical    A ဖြစ်၍ B     A သို့မဟုတ် B     A မဟုတ်        joins truth values
  • The notation tier holds the signs with the precedence of school maths. Its operands are atoms: literals, names, calls and parenthesized expressions.
  • The clause tier holds Burmese phrases. Each operand is a whole notation expression, with the particle that its role needs after it, and a verb closes the clause. A verb takes the operands just before it whose particles it wants, and its result takes the next particle. Particles in Learn shows the common ones.
  • The logical tier joins clauses with ဖြစ်၍, သို့မဟုတ် and မဟုတ်.

A clause can stand in a notation expression, and a logical expression in a clause, just inside parentheses.

စံကား

Expected output

၈
၅
၅၀
၅၀
မှန်

Atoms

  • Number literals and character literals, written as in Source text and words. A number literal without a kind prefix is flexible: it takes the kind that its place wants (a declaration, an assignment, a parameter, the other operand of an operator), and the integer ၃ is an isize when nothing wants another kind. A literal that does not fit is ZK0406. A - right before a literal counts in the range check, so -၁၂၈ fits an ၈ ဘစ် ကိန်းပြည့်.
  • မှန် and မမှန်, the two true/false values.
  • Names of variables, constants, parameters and loop counters. A name that is not declared where it is used is ZK0301 (Names and scope). Inside a function with a result, ရလဒ် names the result variable.
  • Parentheses, ( ... ), around an expression of each kind.
  • Calls, လုပ်ဆောင်ချက် f ကို ... လုပ်ဆောင်သော ရလဒ် (Functions).
  • Places and addresses: p ၏ တန်ဖိုး (Pointers), x ၏ အကွက် i and list literals (Lists).

A string literal is not an expression: it is allowed as the operand of ပြသပါ and nowhere else (ZK0223).

Arithmetic

SignWordsOperation
a + ba နှင့် b ၏ ပေါင်းလဒ်addition
a - ba နှင့် b ၏ နုတ်လဒ်subtraction
a * ba နှင့် b ၏ မြှောက်လဒ်multiplication
a / ba ကို b ဖြင့် စားသော စားလဒ်division (quotient)
a % ba ကို b ဖြင့် စားသော စားကြွင်းremainder
-aအနုတ် anegation

The operands are numbers (integers or decimal numbers) of one common kind, which is the kind of the result; Conversions tells how two kinds are joined. Negation needs a signed integer or a decimal number: -က for an unsigned က is ZK0403. A boolean or a character takes no arithmetic (ZK0403).

Integer division and remainder

Integer division drops the fraction toward zero. The remainder has the sign of the dividend, so each pair satisfies a == (a / b) * b + a % b:

စံကား

Expected output

၃
၂
-၃
-၂
-၃
၂
၂.၅

A zero divisor in an integer division or remainder has no answer. When the compiler can see the zero it refuses the program (ZK0602). When the zero shows up while the program runs, the program stops at that operation (When a program stops).

စံကားZK0602

Expected error

 
စံကား

Expected output

အစ
the program stopped: integer division or remainder with zero as divisor

Decimal numbers never stop the program here: ၁.၀ / ၀.၀ is inf, and ၀.၀ / ၀.၀ is NaN. The remainder of decimal numbers is the C function fmod: ၁၇.၅ % ၅ is ၂.၅.

Overflow

An integer result that does not fit its kind meets one of two fates.

  • When all operands are constants, the compiler works the operation out and a result that does not fit is an error (ZK0601).
  • When an operand is a variable, the operation wraps around at run time: the result is the true result cut to the width of the kind, like an odometer rolling over. Nothing stops the program.
စံကား

Expected output

၄
၂၄၄
၂၅၅
-၁၂၈
၁၂၇

The kind decides the edge: the same sum in a wider kind does not wrap. Pick a kind that is big enough for the numbers at hand; plain ကိန်းပြည့် is a safe choice.

စံကားZK0601

Expected error

error[ZK0601]: + on these constants does not fit i8

Comparison

SignWordsTrue when
a == ba သည် b နှင့် ညီequal
a != ba သည် b နှင့် မညီnot equal
a < ba သည် b အောက် ငယ်less
a > ba သည် b ထက် ကြီးgreater
a <= ba သည် b ထက် မကြီးnot greater
a >= ba သည် b အောက် မငယ်not less

A comparison gives a မှန်မှားတန်ဖိုး. The operands have one common kind (the narrower one is widened first, as in arithmetic). == and != take each kind, including true/false values, characters, addresses and lists of one kind. The ordering operators take numbers and characters. A decimal NaN is equal to nothing, not even itself, and each ordering with it is false.

A comparison cannot be the direct operand of another comparison, in either spelling (ZK0210). Join two comparisons with ဖြစ်၍, or put the inner one in parentheses.

စံကား

Expected output

မှန်
မမှန်
မှန်
မမှန်
မှန်
စံကားZK0210

Expected error

error[ZK0210]: a comparison cannot be the operand of another comparison
help: join the two comparisons with "ဖြစ်၍", or put the inner one in parentheses

An ordering on a true/false value is ZK0403, and so is a condition that is no true/false value (ZK0402).

Logic

SignWordsValue
a && ba ဖြစ်၍ btrue when both are true
a || ba သို့မဟုတ် btrue when either is true
!aa မဟုတ်true when a is false

The operands are true/false values (ZK0403). ဖြစ်၍ and သို့မဟုတ် are short-circuit: when the left side settles the answer, the right side is not worked out, so a call on the right side is not made. မဟုတ် goes after the value as in Burmese, and it negates a whole clause: က == ခ မဟုတ် is !(က == ခ), while !က == ခ is (!က) == ခ.

A logical expression used as a value to print needs parentheses, or the compiler cannot tell where it ends (ZK0204).

စံကား

Expected output

မမှန်
မှန်
စစ်ပြီ
မှန်
စံကားZK0204

Expected error

 

Bitwise operators

SignWordsOperation
a & ba နှင့် b ၏ ဘစ်အလိုက် ဆုံလဒ်and
a | ba နှင့် b ၏ ဘစ်အလိုက် ပေါင်းစုလဒ်or
a ^ ba နှင့် b ၏ ဘစ်အလိုက် ခြားနားလဒ်exclusive or
~aa ၏ ဘစ်အလိုက် ပြောင်းပြန်ပြောင်းလဒ်not (each bit flips)
a << na ကို ဘယ်သို့ n ဘစ် ရွေ့သောရလဒ်shift left
a >> na ကို ညာသို့ n ဘစ် ရွေ့သောရလဒ်shift right

The operands of &, |, ^ and ~ are integers of one common kind. A shift keeps the kind of its left operand. The distance is an unsigned integer (a flexible literal becomes a usize) and it must be less than the bit width of the left operand: a constant distance that is too big is ZK0407, and one that is too big while the program runs stops it. A left shift drops the bits that leave the width. A right shift of a signed integer repeats the sign bit, so -၈ >> ၁ is -၄.

စံကား

Expected output

၁၉၂
၅၃
၄၀
-၄
၁၂
စံကားZK0407

Expected error

 
စံကား

Expected output

အစ
the program stopped: shift distance 64 is not below the bit width 64

Precedence

When an expression holds several operators, the tighter ones bind first, and the operators of one level group from left to right. From the tightest to the loosest:

  1. prefix -, အနုတ်, ~, !;
  2. *, /, %;
  3. +, -;
  4. <<, >>;
  5. &, then ^, then |;
  6. <, >, <=, >=, and then ==, != (none of these chain);
  7. a word clause (... ၏ ပေါင်းလဒ်, ... ထက် ကြီး, ...);
  8. မဟုတ် after a value;
  9. ဖြစ်၍, &&;
  10. သို့မဟုတ်, ||.

Operator precedence gives the full table with examples. Unlike C, the bitwise operators bind tighter than comparison, so ၆ & ၃ == ၂ is (၆ & ၃) == ၂.

စံကား

Expected output

၁၄
၅
၂၆
၁၆
မှန်

Grouping

Parentheses make an expression an atom, override precedence and move an expression between tiers: a clause into a notation expression, and a logical expression into a clause. A conversion is a clause, so (က ကို ဒဿမကိန်း အဖြစ် ပြောင်းလဲသော ရလဒ်) / ၂ needs its parentheses; a call is an atom and needs none.

Parentheses around a whole printed, assigned or returned value change nothing unless the value is a logical expression. The compiler warns about them (ZK0507), as an editor flags a double space; see Natural wording.

စံကားZK0203

Expected error

error[ZK0203]: this statement does not end in a statement verb, found "*"

Constants are worked out first

An operation whose operands are all constants is worked out in the compiler, so ၂ + ၃ * ၄ reaches the VM as ၁၄. This is the reason overflow and a zero divisor in a constant operation are compile errors. zakac run --fold none turns the folding off, and errors in constant operations are still reported.