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