Skip to content
B-MJ HelpBlock-based MiniJava
03 / Blocks

Thirty-four blocks, six categories

The toolbox is organised by MiniJava's grammar rather than by convenience, so the categories are the non-terminals. Once you notice that, finding a block becomes a question about the language rather than a question about the UI.

The toolbox

The B-MJ blocks sidebar showing the Program, Declarations, Types, Statements and Expressions categories with their blocks listed.
Fig. 1 The blocks sidebar. Categories mirror MiniJava's non-terminals.
Category Blocks
Program Class Declaration
Declarations Variable Declaration · Method Declaration · Formal Parameter
Types int[] · boolean · int · String · Identifier Type
Statements Block Statement · if / else · while · System.out.println · Assignment · Array Assignment
Expressions Arithmetic (+ − × ÷) · Compare (< ≤ > ≥) · Logic (&& ||) · Array Lookup · Array Length · charAt · concat · String Length · Method Call · Argument Item · Not · Parenthesized
Values Integer · String Literal · Boolean · Identifier · this · new int[] · new Object

A few of these are worth calling out because their names do not quite give them away:

  • Identifier Type is a class type — how you say Cell x; rather than int x;.
  • Identifier (in Values) is a variable reference, as opposed to the name field on a declaration.
  • Argument Item stacks under a Method Call, one per argument, rather than the call having a fixed number of sockets.
  • Parenthesized only affects how generated source is bracketed.
  • Block Statement is a braced group { … }, which matters wherever the grammar wants a single statement and you have several.
  • charAt, concat and String Length are the String extension, not part of the original BNF.

The grammar-aware renderer

B-MJ uses a custom Blockly renderer called BMJ-Thrasos. It subclasses Blockly's Thrasos renderer and restores grammar-aware connector behaviour: the shape of each socket and plug tells you which non-terminal it is.

Blockly's own connection check metadata still does the enforcing — you cannot plug a statement into an expression socket regardless of what things look like. What the custom shapes add is that you can see the category before you try. Instead of dragging a block over and discovering it will not connect, you can tell from across the workspace that a socket wants an Expression and the thing in your hand is a Statement.

Two different ideas with the same name

B-Lambda also has a custom renderer, Tude, but it is doing something else: Tude changes block geometry so terms read as nested text. BMJ-Thrasos changes connector shapes so grammatical categories are visible. Different problems — a λ-term has three constructs and no interesting grammar, while MiniJava has ten non-terminals and very little else going on visually.

Connector shapes

Ten horizontal connector shapes, one per MiniJava value / non-terminal position:

Non-terminal Appears as the socket for
Goal The program root
MainClass The single main class
ClassDeclaration Each further class
VarDeclaration Fields and locals
MethodDeclaration Methods
FormalParameter Parameters
Type Every type position
Statement Statement positions
Expression Expression positions
Identifier Name positions

Vertical families

Five vertical connector families handle the places MiniJava has a sequence of something. These are the stacking connections — the notches on the top and bottom of a block:

  • Class declarations
  • Variable declarations
  • Method declarations
  • Statements
  • Parameter and argument lists

Because each family is distinct, a statement cannot stack onto a parameter list even though both are “a list of things”. This is also why declarations and statements cannot be interleaved inside a method: they are different vertical families, connected to different sockets.

The grammar

B-MJ implements the CSE 401 MiniJava BNF, plus two additions:

  • The String type and its three operators.
  • The block editor's operator families — where the BNF has separate productions per operator, B-MJ has one block with a dropdown, which keeps the toolbox short without changing the language.

The base grammar is published by the University of Washington as BNF for MiniJava. The project mirrors it, and also keeps an “adjusted” version documenting exactly the grammar it implements — base BNF plus the two additions above.

Only the reachable program is checked

Type checking and execution start from Goal and follow the connections. Blocks left detached on the canvas are ignored — no diagnostics, no execution. Scratch space is genuinely scratch, so you can park a half-built method next to the program while you work on it.

B-MJ is developed at L-Workshop. This help was written against the build running at b-mj.l-workshop.my.id.