This is a followup to my question here.
I got to a point in the program where I felt like I couldn't proceed any further with the current structure, so I did a lot of rewriting. The Statement type is no longer abstract, and each subtype of Statement creates its own instance of Statement's variables. I also removed the abstract execute function from the Statements package because the compiler didn't like that (each subtype will still have its own execute method regardless). The execute function has been changed to a procedure because the incoming Statement type must be modified. I moved statementFactory (formerly createStatement) to the Statement package.
Here is the error I'm getting:
statements-compoundstatements.adb:15:29: expected type "CompoundStatement" defined at statements-compoundstatements.ads:11
statements-compoundstatements.adb:15:29: found type "Statement'Class" defined at statements.ads:6
I'm a beginner at Ada, but my hunch is that because the execute procedure is in CompoundStatements (which is a "subclass" of Statements) it would never be able to see the execute method of another "subclass" of Statements. The only solution I can think of would be to dump all the execute procedures that call an execute procedure into the Statement package, but that seems undesirable. But that still doesn't explain why stmt.all is being used as a type Statement'Class instead of the type created in statementFactory.
Here is the new code:
package Statements is
type Statement is tagged private;
type Statement_Access is access all Statement'Class;
ParserException : Exception;
procedure createStatement(tokens : Vector; S : out Statement);
procedure statementFactory(S: in out Statement; stmt: out Statement_Access);
--.....A bunch of other procedures and functions.....
private
type Statement is tagged
record
tokens : Vector;
executedtokens : Vector;
end record;
end Statements;
procedure createStatement(tokens : Vector; S : out Statement) is
begin
S.tokens := tokens;
end createStatement;
procedure statementFactory(S: in out Statement; stmt: out Statement_Access) is
currenttoken : Unbounded_String;
C : CompoundStatement;
A : AssignmentStatement;
P : PrintStatement;
begin
currenttoken := getCurrentToken(S);
if currenttoken = "begin" then
createStatement(S.tokens, C);
stmt := new CompoundStatement;
stmt.all := Statement'Class(C);
elsif isVariable(To_String(currenttoken)) then
createStatement(S.tokens, A);
stmt := new AssignmentStatement;
stmt.all := Statement'Class(A);
elsif currenttoken = "print" then
createStatement(S.tokens, P);
stmt := new PrintStatement;
stmt.all := Statement'Class(P);
end statementFactory;
package body Statements.CompoundStatements is
procedure execute(skip: in Boolean; C: in out CompoundStatement; reset: out Integer) is
stmt: Statement_Access;
tokensexecuted: Integer;
currenttoken : Unbounded_String;
begin
match(C, "begin");
currenttoken := getCurrentToken(C);
while(currenttoken /= "end") loop
statementFactory(C, stmt);
execute(skip, stmt.all, tokensexecuted); //ERROR OCCURS HERE