| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351 |
- DEFINITION MODULE SymTab;
- IMPORT AST;
- (* Symbol table with static type checking for the M2comp compiler
- (Modula-2 program modules, step 2: semantic analysis, no codegen).
- Base: Test1 SimpleMod2 table (flat scopes with levels, type
- descriptors with aliases, integer-family leniency, InvalidType
- cascade suppression). Extensions for step 2:
- - procedures: nested, value/VAR params, function results; signatures
- persist in procs[] after body scopes pop (no FORWARD headings)
- - local modules (Wirth form): body scope + export table for M.x
- - call checking with an 8-deep frame stack (nested calls safe);
- invalid callees get a dead frame to suppress cascades
- - open arrays (formal-only) + WrapArray/IsOpen helpers
- - loop-depth tracking for EXIT validation (230)
- Error codes follow m2c/Test1: 200 duplicate, 201 undeclared,
- 202 name mismatch, 210 bad assignment, 211 arithmetic, 212 boolean
- operand, 213 comparison, 214 condition, 215 not a record,
- 216 unknown field, 217 not an array, 218 bad index, 219 not a
- pointer, 220 FOR misuse, 221 not a type, 222 set mismatch,
- 223 cyclical type, 224 ordinal required, 230 unsupported construct
- (EXIT outside LOOP, open array outside formal), 232 bad RETURN,
- 233 invalid call. 231 (forward mismatch) unused: no FORWARD.
- - flat scopes with levels: globals at level 0 (duplicates within
- one level rejected, shadowing allowed in nested scopes)
- - every symbol carries a type descriptor index (InvalidType if
- unknown, e.g. imported names); unknown types suppress follow-on
- errors to avoid cascades *)
- CONST
- MaxSyms = 256;
- InvalidType = -1;
- (* symbol kinds *)
- KindConst = 0;
- KindType = 1;
- KindVar = 2;
- KindImport = 3;
- KindModule = 4;
- KindPredef = 5;
- KindField = 6;
- KindProc = 7;
- KindParam = 8;
- KindVarPar = 9;
- (* type classes returned by ClassOf *)
- ClInvalid = 0;
- ClInt = 1;
- ClReal = 2;
- ClChar = 3;
- ClBool = 4;
- ClEnum = 5;
- ClArray = 6;
- ClRecord = 7;
- ClSet = 8;
- ClPtr = 9;
- ClStr = 10;
- (* operator codes; all groups use distinct ranges so a
- tree-walking backend can dispatch on the code alone *)
- OpEq = 20; OpNeq1 = 21; OpNeq2 = 22;
- OpLt = 23; OpLe = 24; OpGt = 25; OpGe = 26;
- OpIn = 27;
- (* operator codes for AddOp / MulOp; MulOp codes are offset *)
- OpAdd = 0; OpSub = 1; OpOr = 2;
- OpTimes = 10; OpSlash = 11; OpDiv = 12; OpMod = 13; OpAnd = 14;
- TYPE
- Name = ARRAY [0 .. 63] OF CHAR;
- TypeIndex = INTEGER;
- BoundsArr = ARRAY [0 .. 7] OF INTEGER;
- (* Per-dimension bounds for WrapArrayB (Coco/R attribute type). *)
- (* ---------------- symbols and scopes ---------------- *)
- PROCEDURE Init;
- (* Clears the table and enters predefined identifiers
- (INTEGER, CARDINAL, SHORTINT, LONGINT, REAL, LONGREAL, CHAR,
- BOOLEAN, TRUE, FALSE, NIL). *)
- PROCEDURE Enter (name: ARRAY OF CHAR; kind: INTEGER): BOOLEAN;
- (* Enters name at the current scope level (type InvalidType).
- Returns FALSE on duplicate within the same level. *)
- PROCEDURE EnterPending (name: ARRAY OF CHAR; kind: INTEGER): BOOLEAN;
- (* Like Enter, but remembers the entry for a later FixPending call
- (used for VAR identifier lists whose type is parsed afterwards).
- Returns FALSE on duplicate (entry not recorded). *)
- PROCEDURE FixPending (t: TypeIndex);
- (* Assigns type t to all pending entries, clears the buffer. *)
- PROCEDURE FieldPending (rec: TypeIndex; name: ARRAY OF CHAR): BOOLEAN;
- (* Records a field name for record descriptor rec (type fixed later
- with FixPendingF). Returns FALSE on duplicate field. *)
- PROCEDURE FixPendingF (rec: TypeIndex; t: TypeIndex);
- (* Assigns type t to pending fields owned by rec. *)
- PROCEDURE Lookup (name: ARRAY OF CHAR): BOOLEAN;
- (* TRUE if name is visible (innermost scope wins). *)
- PROCEDURE SymType (name: ARRAY OF CHAR): TypeIndex;
- (* Type of innermost visible entry, InvalidType if absent. *)
- PROCEDURE SetSymType (name: ARRAY OF CHAR; t: TypeIndex);
- (* Sets type of innermost visible entry. *)
- PROCEDURE SymKind (name: ARRAY OF CHAR): INTEGER;
- (* Kind of innermost visible entry, -1 if absent. *)
- PROCEDURE Equal (a, b: ARRAY OF CHAR): BOOLEAN;
- PROCEDURE PushScope;
- PROCEDURE PopScope;
- (* WITH statement support: PushRecord pushes a record's fields. *)
- PROCEDURE PushRecord (t: TypeIndex): BOOLEAN;
- (* Pushes a scope containing t's fields (as KindField). FALSE if t
- is not a record type (or invalid). Caller must PopScope after.
- Kept for a future WITH statement; unused by the step-2 grammar. *)
- PROCEDURE PrintTable;
- (* ---------------- procedures ---------------- *)
- (* Signatures live in procs[]/params[] keyed by a per-procedure number
- stored on the symbol, so they survive PopScope (nested and exported
- procedures stay callable). No FORWARD headings in step 2. *)
- PROCEDURE EnterProc (name: ARRAY OF CHAR): BOOLEAN;
- (* Enters a KindProc name in the current scope, assigns the next proc
- number with an empty signature. FALSE on duplicate or table full.
- Sets the current-proc context for EnterParamPending calls. *)
- PROCEDURE OpenProcScope;
- (* Pushes a body scope for the current procedure (depth + 1, fresh
- return-type context). *)
- PROCEDURE CloseProc;
- (* Pops the procedure body scope, restores the enclosing context. *)
- PROCEDURE EnterParamPending (name: ARRAY OF CHAR; isVar: BOOLEAN): BOOLEAN;
- (* Like EnterPending for FPSection identifier lists whose type is
- parsed afterwards. FALSE on duplicate (not recorded). *)
- PROCEDURE FixParamPending (t: TypeIndex): BOOLEAN;
- (* Enters all pending parameters of the current procedure with type t
- (KindParam or KindVarPar), appends them to its signature. FALSE if
- any entry failed (duplicate or table full). *)
- PROCEDURE SetProcRet (t: TypeIndex);
- (* Sets the return type of the current procedure (InvalidType =
- proper procedure) and of the current return-type context. *)
- PROCEDURE ProcNum (name: ARRAY OF CHAR): INTEGER;
- (* Proc number of the visible procedure, or -1 if absent / not one. *)
- PROCEDURE ProcRet (name: ARRAY OF CHAR): TypeIndex;
- PROCEDURE ProcNPar (name: ARRAY OF CHAR): CARDINAL;
- PROCEDURE ParamType (name: ARRAY OF CHAR; i: CARDINAL): TypeIndex;
- PROCEDURE ParamIsVar (name: ARRAY OF CHAR; i: CARDINAL): BOOLEAN;
- (* Signature queries by name (InvalidType/0/FALSE if absent). *)
- PROCEDURE ProcRetByNum (num: INTEGER): TypeIndex;
- PROCEDURE ProcNParByNum (num: INTEGER): CARDINAL;
- PROCEDURE ParamTypeByNum (num: INTEGER; i: CARDINAL): TypeIndex;
- PROCEDURE ParamIsVarByNum (num: INTEGER; i: CARDINAL): BOOLEAN;
- (* Same queries keyed by procedure number (exported module procs). *)
- PROCEDURE InProc (): BOOLEAN;
- (* TRUE inside a procedure body. *)
- PROCEDURE InFunction (): BOOLEAN;
- (* TRUE inside a function (non-InvalidType return) body. *)
- PROCEDURE CurRet (): TypeIndex;
- (* Current return type (InvalidType = proper procedure or outside). *)
- (* ---------------- local modules (Wirth form) ---------------- *)
- (* Local MODULEs nest at any level. EXPORT names resolve at END into
- the export table keyed by (module, name); M.x qualified access
- consults it, or the live body scope from inside M itself. *)
- PROCEDURE EnterModule (name: ARRAY OF CHAR): BOOLEAN;
- (* Enters KindModule + pushes the body scope + module context.
- FALSE on duplicate. *)
- PROCEDURE ModuleAddExp (name: ARRAY OF CHAR): BOOLEAN;
- (* Records an export name for the current module. FALSE if not in a
- module, on duplicate, or when the export list is full. *)
- PROCEDURE ExitModule (): BOOLEAN;
- (* Resolves exports against the body scope into the export table,
- pops scope + context. FALSE when an EXPORT name was not declared
- (ghost export). *)
- PROCEDURE InModule (): BOOLEAN;
- (* TRUE inside a local MODULE body (including its procedures). *)
- PROCEDURE CurModName (VAR m: Name);
- (* Innermost module name, empty if none. *)
- PROCEDURE ExpKind (mod, exp: ARRAY OF CHAR): INTEGER;
- (* Exported kind, -1 if absent. *)
- PROCEDURE ExpType (mod, exp: ARRAY OF CHAR): TypeIndex;
- (* Exported type (InvalidType if absent / not a typed export). *)
- PROCEDURE ExpProc (mod, exp: ARRAY OF CHAR): INTEGER;
- (* Exported proc number, -1 if absent / not a procedure. *)
- PROCEDURE SelfKind (mod, exp: ARRAY OF CHAR): INTEGER;
- (* Kind of exp as M.exp from inside M itself (live body scope at
- body level, since exports resolve only at END). -1 if absent. *)
- PROCEDURE SelfType (mod, exp: ARRAY OF CHAR): TypeIndex;
- (* Type of an M.exp self reference (InvalidType if absent). *)
- PROCEDURE SelfProc (mod, exp: ARRAY OF CHAR): INTEGER;
- (* Proc number of an M.exp self reference (-1 if absent). *)
- (* ---------------- call checking ---------------- *)
- (* An 8-deep frame stack keeps nested calls (f(g(x))) safe. A dead
- frame (proc -1) accepts everything: the grammar pushes one for
- invalid callees so actuals parse without cascade errors. *)
- PROCEDURE CallBeginNum (num: INTEGER);
- (* Opens a call frame for procedure num (-1 = dead frame). *)
- PROCEDURE CallActual (t: TypeIndex; isVar: BOOLEAN): BOOLEAN;
- (* Checks one actual against the current formal (VAR formals need a
- storable designator of identical type, value formals need
- assignment compatibility) and advances. FALSE on mismatch. *)
- PROCEDURE CallEndNum (n: CARDINAL): BOOLEAN;
- (* Closes the frame; FALSE on arity mismatch (n # formals). *)
- (* ---------------- loops ---------------- *)
- PROCEDURE LoopEnter;
- PROCEDURE LoopExit;
- PROCEDURE InLoop (): BOOLEAN;
- (* Innermost LOOP tracking for EXIT validation (error 230). *)
- (* ---------------- type descriptors ---------------- *)
- PROCEDURE NewAlias (): TypeIndex;
- PROCEDURE NewSub (base: TypeIndex): TypeIndex;
- PROCEDURE NewEnum (): TypeIndex;
- PROCEDURE NewArray (elem: TypeIndex): TypeIndex;
- PROCEDURE NewOpen (elem: TypeIndex): TypeIndex;
- PROCEDURE WrapArray (elem: TypeIndex; dims: CARDINAL): TypeIndex;
- (* WrapArray nests elem in dims ARRAY levels (dims = 0 gives an open
- array). Open arrays are formal-only (grammar reports 230). *)
- PROCEDURE IsOpen (t: TypeIndex): BOOLEAN;
- PROCEDURE NewSubB (base: TypeIndex; lo, hi: INTEGER): TypeIndex;
- PROCEDURE NewArrayB (elem: TypeIndex; lo, hi: INTEGER): TypeIndex;
- PROCEDURE WrapArrayB (elem: TypeIndex; los, his: BoundsArr;
- dims: CARDINAL): TypeIndex;
- (* Bounded nesting for ARRAY index lists (dims = 0 gives an open
- array). Bounds come from folded index expressions (grammar). *)
- PROCEDURE IndexBounds (t: TypeIndex; VAR lo, hi: INTEGER): BOOLEAN;
- (* Finite bounds of an index type: subrange (stored), CHAR (0..255),
- BOOLEAN (0..1). FALSE for INTEGER/CARDINAL (unbounded) and
- anything else (grammar reports 230). *)
- PROCEDURE ArrayLo (t: TypeIndex): INTEGER;
- PROCEDURE ArrayHi (t: TypeIndex): INTEGER;
- PROCEDURE ArrayLen (t: TypeIndex): CARDINAL;
- PROCEDURE TypeSlots (t: TypeIndex): CARDINAL;
- (* Stack slots for a value: 1 per scalar/pointer/set, len*elem for
- arrays, summed members for records. Cycle-guarded. *)
- PROCEDURE FieldOffset (rec: TypeIndex; name: ARRAY OF CHAR): INTEGER;
- (* Slot offset of a record field in declaration order. *)
- PROCEDURE NewRecord (): TypeIndex;
- PROCEDURE NewSet (base: TypeIndex): TypeIndex;
- PROCEDURE NewPtr (base: TypeIndex): TypeIndex;
- PROCEDURE NewStr (): TypeIndex;
- (* Fresh descriptors; base/elem may be InvalidType. InvalidType is
- returned when the table is full. *)
- PROCEDURE SetTarget (t, base: TypeIndex);
- (* Sets an alias target (TYPE declaration completion). *)
- PROCEDURE IntType (): TypeIndex;
- PROCEDURE RealType (): TypeIndex;
- PROCEDURE CharType (): TypeIndex;
- PROCEDURE BoolType (): TypeIndex;
- PROCEDURE ClassOf (t: TypeIndex): INTEGER;
- (* Resolves aliases; InvalidType maps to ClInvalid. *)
- PROCEDURE IsIntFamily (t: TypeIndex): BOOLEAN;
- (* INTEGER, CARDINAL or subrange thereof (Invalid suppresses). *)
- PROCEDURE SameType (a, b: TypeIndex): BOOLEAN;
- (* Same resolved descriptor (Invalid suppresses). *)
- PROCEDURE FieldExists (rec: TypeIndex; name: ARRAY OF CHAR): BOOLEAN;
- PROCEDURE FieldType (rec: TypeIndex; name: ARRAY OF CHAR): TypeIndex;
- PROCEDURE ArrayElem (t: TypeIndex): TypeIndex;
- PROCEDURE PtrBase (t: TypeIndex): TypeIndex;
- (* ---------------- predicates used by grammar checks ---------------- *)
- (* All return TRUE if either operand is InvalidType (no cascades). *)
- PROCEDURE Assignable (src, dst: TypeIndex): BOOLEAN;
- (* Assignment compatibility (210). *)
- PROCEDURE ArithCheck (l, r: TypeIndex; divmod: BOOLEAN;
- VAR res: TypeIndex): BOOLEAN;
- (* + - * / (divmod FALSE) or DIV MOD (TRUE); res is result type (211). *)
- PROCEDURE UnaryCheck (t: TypeIndex; VAR res: TypeIndex): BOOLEAN;
- (* Unary + - (part of 211). *)
- PROCEDURE BoolCheck (t: TypeIndex): BOOLEAN;
- (* BOOLEAN required: NOT/AND/OR operands (212), conditions (214). *)
- PROCEDURE RelCheck (l, r: TypeIndex; op: INTEGER): BOOLEAN;
- (* = # <> < <= > >= IN (213/222 chosen by caller via op). *)
- PROCEDURE EqCheck (l, r: TypeIndex): BOOLEAN;
- (* = # compatibility, also reused for CASE label matching. *)
- PROCEDURE InCheck (l, set: TypeIndex): BOOLEAN;
- PROCEDURE SetElemCheck (first, elem: TypeIndex): BOOLEAN;
- PROCEDURE SetFor (elem: TypeIndex): TypeIndex;
- (* Fresh SET OF elem descriptor for set literals. *)
- PROCEDURE StrLen (s: ARRAY OF CHAR): CARDINAL;
- (* ---------------- compile-time constants ---------------- *)
- (* Integer values of CONST declarations, recorded at parse time for
- array/subrange bound folding (grammar) and MGen lookups. Chained
- consts fold (Neg = -N + 2 with N = 10 gives -8); anything else
- stays undefined (bounds then report 230). *)
- PROCEDURE NoteConst (name: ARRAY OF CHAR; v: INTEGER; ok: BOOLEAN);
- (* Records the folded value of a just-declared CONST (ok = foldable). *)
- PROCEDURE ConstVal (name: ARRAY OF CHAR; VAR v: INTEGER): BOOLEAN;
- (* Value of the visible integer CONST (TRUE/FALSE predefs included);
- FALSE if absent, non-const, or undefined. *)
- PROCEDURE ConstFold (n: AST.Node; VAR v: INTEGER): BOOLEAN;
- (* Folds nkInt / nkUn(+/-) / const nkName nodes. Needs AST import. *)
- END SymTab.
|