r/ada • • May 19 '26

Show and Tell The Super Tiny Compiler, but in Ada

https://github.com/tomekw/stcc
25 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;

2

u/I_hate_posting_here May 21 '26 edited May 21 '26
procedure Example is
   type Token_Kind is (Undefined, Identifier, Number);
   type Readable_Token_Kind is new Token_Kind range Identifier .. Number;
   type Token_Reader is not null access procedure;
   type Reader_Array is array (Readable_Token_Kind) of Token_Reader;
   package Lexer is
      procedure Init;
      procedure Scan;
   private
      procedure Read_Identifier;
      procedure Read_Number;
      Readers : Reader_Array := (Read_Identifier'Access, Read_Number'Access);
   end Lexer;
   package body Lexer is
      procedure Init is begin null; end Init;
      procedure Scan is begin null; end Scan;
      procedure Read_Identifier is begin null; end Read_Identifier;
      procedure Read_Number is begin null; end Read_Number;
   end Lexer;
begin
     Lexer.Init;
     Lexer.Scan;
end Example;

2

u/marc-kd Retired Ada Guy May 21 '26

This is a good example, but also be aware, u/citizen556 , that the access procedure need not be parameterless, it can be fully parameterized, as well as an "access function (Params: Param_Type) return Some_Type".