Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 1 addition & 13 deletions lolcode/spec/expressions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,6 @@ Math is performed as integer math in the presence of two ``NUMBR`` s.
If either of the arguments is a ``YARN``, the ``YARN`` is
converted to an integer and the operation proceeds if the conversion succeeds.

Precedence
~~~~~~~~~~

Multiplication, division and modulo have the highest precedence. All three
operators have equal precedence and are evaluated left to right.
Addition and subtraction have equal precedence and are also evaluated left to
right.

Parenthesis ('()') can be used to group operations to override precedence or
clarify the evaluation order.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

precedence is implicit because of the operators

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the parenthesis because I didn't understand how precedence works. Can you show me some examples? Can we put them in the spec so it's clear for the students?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might get it: is x+2*y written as sum of x an produkt of 2 an y?

@novo52 novo52 Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, exactly. And (x+2)*y is written as produkt of sum of x an 2 an y

Conditions
~~~~~~~~~~

Expand All @@ -42,8 +31,7 @@ LOLCODE supports two conditional operators:
BIGGR OF <x> AN <y> BTW max
SMALLR OF <x> AN <y> BTW min

These operators apply to both strings and integers. Since both types are
supported, the types of ``<x>`` and ``<y>`` must match.
These operators apply to both strings and integers. As with the math operators above, if either argument is a ``YARN``, it is converted to an integer and the operation proceeds if the conversion succeeds.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was going from the compare op in the spec:

Comparisons are performed as integer math in the presence of two NUMBRs, but if either of the expressions are NUMBARs, then floating point math takes over. Otherwise, there is no automatic casting in the equality, so BOTH SAEM "3" AN 3 is FAIL.


Concatenation
~~~~~~~~~~~~~
Expand Down
4 changes: 3 additions & 1 deletion lolcode/spec/statements.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ Our version of LOLCODE supports seven types of statements:
If-then
~~~~~~~

A bare expression statement (one not assigned to a variable) stores its result in the implicit variable ``IT``. ``IT`` holds that value until the next bare expression replaces it, and is what ``O RLY?`` and ``WTF?`` test against.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IT is used in a bunch of places in the spec, but not anywhere else in our spec. Do you think we should introduce it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Decision: Remove IT, use explicit conditions in every case


An if statement begins with a comparison:

Comparison is (currently) done with two binary equality operators:
Expand Down Expand Up @@ -179,7 +181,7 @@ Iteration loops have the form:

Where ``<operation>`` may be ``UPPIN`` (increment by one) or ``NERFIN`` (decrement by one).
That operation/function is applied to the ``<variable>``, which is temporary, and local to the loop.
The ``TIL <expression>`` evaluates the expression as a boolean: if it evaluates as false, the loop continues once more, if not, then loop execution stops, and continues after the matching ``IM OUTTA YR <label>``. The ``WILE <expression>`` is the converse: if the expression is true, execution continues, otherwise the loop exits.
The TIL/WILE condition, when present, is checked before each iteration of the loop body, including the first — so a loop can execute zero times. The ``TIL <expression>`` evaluates the expression as a boolean: if it evaluates as false, the loop continues once more, if not, then loop execution stops, and continues after the matching ``IM OUTTA YR <label>``. The ``WILE <expression>`` is the converse: if the expression is true, execution continues, otherwise the loop exits.

.. _sssec:cast:

Expand Down
6 changes: 4 additions & 2 deletions lolcode/spec/variables.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ Scope
All variable scope is local to the main program block.
Variables are only accessible after declaration, and there is no global scope.

Blocks introduced by ``O RLY?``/``YA RLY``/``MEBBE``/``NO WAI``, ``WTF?``/``OMG``, and ``IM IN YR``/``IM OUTTA YR`` are their own scope: a variable declared with ``I HAS A`` inside one of these blocks is only visible within that block, and ceases to exist once the block ends.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this is the intention, we may also want a single global scope? However, the

IM IN YR <label> <operation> YR <variable> [TIL|WILE <expression>]
  <code block>
IM OUTTA YR <label>

loop has a temporary local variable, so they have to do scoping anyway.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought I had a Scope section that reads something like:

All variable scope, as of this version, is local to the enclosing function or to the main program block. Variables are only accessible after declaration, and there is no global scope.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is that section. However,

  1. This version does not have functions
  2. <variable> in the loop example above is local according to the spec, so your scope rule alone is inconsistent with this part of the spec.

I would prefer that we have no scope, as SCalc has no scope and I have written VCalc exams with the assumption that VCalc introduces scoping. However, IDK how to resolve this—maybe the loop requires an already declared variable?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My reading of the Scope section is that there is no scope since we don't have functions, i.e. it already was like SCalc. Somehow I thought you were adding block scoping with your suggested changes.

I suggest we resolve the weird loop iterators exactly as intended by the spec: they are special variables that do not need to be declared and only exist within their loop body. That's the great fun of inventing your own language - you can do whatever you want!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is what I was saying, but I no longer hold that position.

I am thinking of how the student implement the parser/interpreter. If there are these temporary variables that only exist within the loop body, then they must implement a scope table—which they did not have to do for SCalc. Then, lolcode does not have global scope, it also has block scoping rules, but only for this one specific part of the language.

I think this is not educational for the students, and we should either do real block scoping (not recommended) or get rid of this specific type of block scoping (recommended).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Decision: advise students they should not bother with a scope table, all global scope except for implicit loop vars.

Note: investigate nested loops


Naming
~~~~~~

Expand All @@ -15,13 +17,13 @@ Variable identifiers may be in all uppercase or lowercase letters (or a mixture
Types
~~~~~

For the purposes of this assignment, LOLCODE only recognizes three types:
For the purposes of this assignment, LOLCODE recognizes four types, though only three of them can be declared as variables:

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is like SCalc

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SCalc (and VCalc) only have integers. I found the interpreter was much trickier to write with two types (and automatic promotion). It actually made we want to do more passes (symbol creation and type checking) before doing the interpreter.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I say "this is like SCalc", I mean that SCalc also has an implicit boolean type that exists for conditionals but can not be explicitly created by the programmer.


- **YARN** or strings. Literals are enclosed in double quotes ('"') at each end. We are not going to try to support escape characters for this assignment.

- **NUMBR** or integers. Integers can be represented using the host's 32-bit implementation. Integer literals are allowed to have a leading hyphen ('-') to signify a negative number.

- **TROOF** or boolean, where true is WIN and false is FAIL. Although full LOLCODE supports both variables and expressions of type TROOF, we only include it here for reference in the the descriptions taken from the spec.
- **TROOF** or boolean, where true is WIN and false is FAIL. TROOF is a value type produced by comparisons (``BOTH SAEM``, ``DIFFRINT``) and consumed by conditionals (``O RLY?``, ``MEBBE``), but it cannot be declared as a variable or cast to with MAEK in this reduced version of the language.

- **NOOB** or void. This is the type given to uninitialized variables.

Expand Down
Loading