2
votes

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
1

1 Answers

5
votes

You say “I also removed the abstract execute function from the Statements package because the compiler didn't like that”; but you really need it, because otherwise how is the compiler to know that when you call execute (skip, stmt.all, tokensexecuted) that any stmt.all will provide an execute for it to dispatch to?

Not only does the extended type inherit the attributes of its parent type (so each CompoundStatement etc already has tokens and executedtokens), it inherits the primitive operations of the parent; if the parent operation is abstract, the child must provide its own implementation, if not, the child can provide its own (overriding) implementation.

See the Ada 95 Rationale and Wikibooks for good discussions on this.