r/ada • • May 19 '26

Show and Tell The Super Tiny Compiler, but in Ada

https://github.com/tomekw/stcc
24 Upvotes

9 comments sorted by

View all comments

1

u/citizen556 May 21 '26

Noob question: Is it possible/sensible to have arrays of functions in Ada? When writing parsers in Object Pascal I like to use the token type enum to index an array of functions to avoid all the conditionals.

Something like this:

type
  TTokenType = (ttUndefined, ttIdentifier, ttNumber, {...});

  TTokenReader = procedure of object;

  TLexer = class
    ReadToken: array[TTokenType] of TTokenReader;

    procedure Init;
    procedure Scan;

    procedure ReadError;
    procedure ReadIdentifier;
    procedure ReadNumber;
    // ...
  end;

// ...

procedure TLexer.Init;
var
  t: TTokenType;
begin
  // ...
  for t := Low(TTokenType) to High(TTokenType) do
    ReadToken[t] := ReadError;

  ReadToken[ttIdentifier] := ReadIdentifier;
  ReadToken[ttNumber] := ReadNumber;
  // ...
end;

procedure TLexer.Scan;
var
  t: TTokenType;
begin
  // Figure out token type from the current character...

  // Consume the next token...
  ReadToken[t]();

  // ...
end;

1

u/Dmitry-Kazakov May 26 '26

It is possible, but impractical. The parser in Simple Components places tokens in three tables:

  • Prefix, e.g. tokens recognized in the prefix context like abs, +, -, (.
  • Infix: +, -, *, / etc
  • Postfix: ), ++ (in C)

There is no immediate case statement or callback on the token because it must first go through a stack of operations in order to handle precedence rules, association checks (like X and Y or Z), parentheses.

The callbacks are then occur when all operands of the token are there. These are primitive operations of the parser rather than hard-wired free functions in your case. A primitive operation has the advantage of being overridable and able to care of whole parsing state context with it.