-
Notifications
You must be signed in to change notification settings - Fork 0
AST Generation From Source
A file node encodes the filename, checksum (module key) and source code (compilation unit) of a Modula-2 source file. It is the root node of the abstract syntax tree.
An interface source file Foobar.def
is encoded as
(FILE (FILENAME "Foobar.def") (Key 0xDEADBEEF) (INTERFACE ...))
An implementation source file Foobar.mod
is encoded as
(FILE (FILENAME "Foobar.mod") (Key 0xCAFEBABE) (IMPLEMENTATION ...))
A program source file FooProg.mod
is encoded as
(FILE (FILENAME "FooProg.mod") (Key 0xCAFED00D) (PROGRAM ...))
A file node is created using the AST API call
ast_node = m2c_ast_new_node(AST_FILE,
filename_node, key_node, module_node, NULL);
An interface module node encodes the module identifier, import list, re-export list, definitions and declarations within an interface module.
INTERFACE MODULE Foobar;
...
END Foobar.
is encoded as
(INTERFACE (IDENT "Foobar")
(IMPORT ...)
(RE-EXPORT ...)
(DECL-LIST ...))
An interface module node is created using the AST API call
ast_node = m2c_ast_new_node(AST_INTERFACE,
id_node, imp_node, rxp_node, def_or_decl_node, NULL);
An implementation module node encodes the module identifier, import list, definitions and initialisation code of an implementation module.
IMPLEMENTATION MODULE Foobar;
...
END Foobar.
is encoded as
(IMPLEMENTATION (IDENT "Foobar")
(IMPORT ...)
(DEF-LIST ...)
(STMTSEQ ...))
An implementation module node is created using the AST API call
ast_node = m2c_ast_new_node(AST_IMPLEMENTATION,
id_node, imp_node, def_node, init_node, NULL);
A program module node encodes the module identifier, import list, definitions and execution code of a program module.
MODULE FooProg;
...
END FooProg.
is encoded as
(PROGRAM (IDENT "FooProg")
(IMPORT ...)
(DEF-LIST ...)
(STMTSEQ ...))
A program module node is created using the AST API call
ast_node = m2c_ast_new_node(AST_PROGRAM,
id_node, imp_node, def_node, exec_node, NULL);
An import list node encodes all imported library identifiers within an interface module in the order they appear in the Modula-2 source.
IMPORT Foo, Bar;
IMPORT Baz;
is encoded as
(IMPORT "Foo" "Bar" "Baz")
An import list node is created using the AST API call
ast_node = m2c_ast_new_terminal_list_node(AST_IMPORT, imp_list);
where imp_list
is a
FIFO API created object of type fifo_t
and the list elements are interned strings of type intstr_t
.
A re-export list node encodes all re-exported library identifiers within an interface module in the order they appear within the Modula-2 source.
IMPORT Foo+, Bar;
IMPORT Baz+;
is encoded as
(IMPORT "Foo" "Bar" "Baz")
and
(RE-EXPORT "Foo" "Baz")
A re-export list node is created using the AST API call
ast_node = m2c_ast_new_terminal_list_node(AST_REEXPORT, rxp_list);
where rxp_list
is a
FIFO API created object of type fifo_t
and the list elements are interned strings of type intstr_t
.
A declaration list node encodes all definitions and declarations within an interface module in the order they appear in the Modula-2 source.
CONST Foo = 42;
TYPE Bar = Baz;
PROCEDURE Bam;
is encoded as
(DECL-LIST
(CONSTDEF (IDENT "Foo") (INTVAL 42))
(TYPEDEF (IDENT "Bar") (IDENT "Baz"))
(PROCDECL (PSIG (IDENT "Bam") (EMPTY) (EMPTY))))
A declaration list node is created using the AST API call
ast_node = m2c_ast_new_list_node(AST_DECLLIST, decl_list);
where decl_list
is a
FIFO API created object of type fifo_t
and the list elements are AST nodes of type m2c_astnode_t
.
A definition list node encodes all definitions within an implementation or program module in the order they appear in the Modula-2 source.
CONST Foo = 42;
TYPE Bar = Baz;
VAR ch : CHAR;
PROCEDURE Bam;
BEGIN
NOP
END Bam;
is encoded as
(DEF-LIST
(CONSTDEF (IDENT "Foo") (INTVAL 42))
(TYPEDEF (IDENT "Bar") (IDENT "Baz"))
(VARDEF (IDENT "ch") (IDENT "CHAR"))
(PROCDEF (PSIG (IDENT "Bam") (EMPTY) (EMPTY) (STMTSEQ (NOP)))))
A definition list node is created using the AST API call
ast_node = m2c_ast_new_list_node(AST_DEFLIST, def_list);
where def_list
is a
FIFO API created object of type fifo_t
and the list elements are AST nodes of type m2c_astnode_t
.
A constant definition node encodes the identifier, optionally a type, and the value expression of a constant definition.
CONST Foo = 42;
is encoded as
(CONSTDEF (IDENT "Foo") (EMPTY) (INTVAL 42))
A constant definition node is created using the AST API call
ast_node = m2c_ast_new_node(AST_CONSTDEF,
id_node, type_node, expr_node, NULL);
where type_node
may be an empty node.
A type declaration node encodes the identifier, and optionally the allocation size of a type declaration within an interface module.
TYPE FooPtr = OPAQUE;
TYPE BarRec = OPAQUE [AllocSize];
is encoded as
(TYPEDECL (IDENT "FooPtr") (EMPTY))
(TYPEDECL (IDENT "BarRec") (IDENT "AllocSize"))
A type declaration node is created using the AST API call
ast_node = m2c_ast_new_node(AST_TYPEDECL,
id_node, expr_node, NULL);
where expr_node
may be an empty node.
A type definition node encodes the identifier and type constructor of a type definition within an interface, implementation or program module.
TYPE FooPtr = POINTER TO Foo;
is encoded as
(TYPEDEF (IDENT "FooPtr") (POINTER (IDENT "Foo"))
A type definition node is created using the AST API call
ast_node = m2c_ast_new_node(AST_TYPEDEF,
id_node, type_node, NULL);
A variable declaration node encodes the identifier or identifier list, and type of a variable definition within an interface module.
VAR foo, bar : Foobar;
is encoded as
(VARDECL (IDENTLIST "foo" "bar") (IDENT "Foobar"))
A variable declaration node is created using the AST API call
ast_node = m2c_ast_new_node(AST_VARDECL,
ident_node, type_node, NULL);
where ident_node
may be an identifier or identifier list node, and type_node
an identifier or anonymous type constructor node.
A variable definition node encodes the identifier or identifier list, and type of a variable definition within an implementation or program module.
VAR foo, bar : Foobar;
is encoded as
(VARDEF (IDENTLIST "foo" "bar") (IDENT "Foobar"))
A variable definition node is created using the AST API call
ast_node = m2c_ast_new_node(AST_VARDEF,
ident_node, type_node, NULL);
where ident_node
may be an identifier or identifier list node, and type_node
an identifier or anonymous type constructor node.
A procedure declaration node encodes the procedure signature of a procedure declaration within an interface module.
PROCEDURE default : Foobar;
is encoded as
(PROCDECL
(PSIG
(IDENT "default") ; procedure identifier
(EMPTY) ; formal parameters
(IDENT "Foobar"))) ; return type
A procedure declaration node is created using the AST API call
ast_node = m2c_ast_new_node(AST_PROCDECL,
psig_node, NULL);
A procedure definition node encodes the procedure signature and body of a procedure definition within an implementation or program module.
PROCEDURE default : Foobar;
BEGIN
RETURN defaultValue
END default;
is encoded as
(PROCDEF
(PSIG
(IDENT "default") ; procedure identifier
(EMPTY) ; formal parameters
(IDENT "Foobar")) ; return type
(STMTSEQ
(RETURN (IDENT "defaultValue"))))
A procedure definition node is created using the AST API call
ast_node = m2c_ast_new_node(AST_PROCDEF,
psig_node, body_node, NULL);
A constant binding node encodes the binding of a constant definition within an interface module.
CONST [TLIMIT] Capacity = 1000;
is encoded as
(CONSTDEF (IDENT "Capacity") (INTVAL 1000))
and
(BIND-CONST (IDENT "Capacity") (IDENT "TypeIdent") (IDENT "TLIMIT"))
A constant binding node is created using the AST API call
ast_node = m2c_ast_new_node(AST_BINDCONST,
id_node, type_node, bind_spec_node, NULL);
A procedure binding node encodes the binding of a procedure declaration within an interface module.
PROCEDURE [LENGTH] length ( str : String ) : LONGCARD ;
is encoded as
(PROCDECL
(PSIG
(IDENT "length") ; procedure identifier
(BYVAL (IDENT "str") (IDENT "String")) ; formal parameters
(IDENT "LONGCARD"))) ; return type
and
(BIND-PROC (IDENT "length") (IDENT "String") (IDENT "LENGTH"))
A procedure binding node is created using the AST API call
ast_node = m2c_ast_new_node(AST_BINDPROC,
id_node, type_node, bind_spec_node, NULL);
A formal parameters sequence node encodes the formal parameters of a procedure signature.
A formal parameters sequence node is created using the AST API call
ast_node = m2c_ast_new_list_node(AST_FPSEQ, node_list);
where node_list
is a
FIFO API created object of type fifo_t
and the list elements are AST nodes of type m2c_astnode_t
.
A formal parameters node encodes one or more formal parameters of a procedure signature.
There are three kinds:
- BYVAL : formal value parameters node
- BYREF : formal var parameters node
- CONSTREF : formal const parameters node
A BYVAL formal parameters node encodes one or more formal by-value parameters of a procedure signature.
PROCEDURE Foo ( bar, baz : Bam );
is encoded as
(PROCDECL
(PSIG
(IDENT "Foo") ; procedure identifier
(BYVAL
(IDENTLIST "bar" "baz") ; formal parameter identifiers
(IDENT "Bam")) ; formal type identifier
(EMPTY))) ; no return type
A BYVAL formal parameters node is created using the AST API call
ast_node = m2c_ast_new_node(AST_BYVAL,
id_node, type_node, formal_type_node, NULL);
where id_node
may be an identifier or identifier list node.
A BYREF formal parameters node encodes one or more formal by-reference parameters of a procedure signature.
PROCEDURE Foo ( VAR bar, baz : Bam );
is encoded as
(PROCDECL
(PSIG
(IDENT "Foo") ; procedure identifier
(BYREF
(IDENTLIST "bar" "baz") ; formal parameter identifiers
(IDENT "Bam")) ; formal type identifier
(EMPTY))) ; no return type
A BYREF formal parameters node is created using the AST API call
ast_node = m2c_ast_new_node(AST_BYREF,
id_node, type_node, formal_type_node, NULL);
where id_node
may be an identifier or identifier list node.
A CONSTREF formal parameters node encodes one or more formal immutable by-reference parameters of a procedure signature.
PROCEDURE Foo ( CONST bar, baz : Bam );
is encoded as
(PROCDECL
(PSIG
(IDENT "Foo") ; procedure identifier
(CONSTREF
(IDENTLIST "bar" "baz") ; formal parameter identifiers
(IDENT "Bam")) ; formal type identifier
(EMPTY))) ; no return type
A CONSTREF formal parameters node is created using the AST API call
ast_node = m2c_ast_new_node(AST_CONSTREF,
id_node, type_node, formal_type_node, NULL);
where id_node
may be an identifier or identifier list node.
A formal type node encodes a formal type for one or more formal parameters of a procedure signature.
There are four kinds:
- non-attributed formal type node
- ARRAYOF : open array formal type node
- ARGLIST : variadic formal type node
- CAST : casting formal type node
An open array formal type node encodes an open array formal type for one or more formal parameters of a procedure signature.
PROCEDURE Foo ( bar, baz : ARRAY OF Bam );
is encoded as
(PROCDECL
(PSIG
(IDENT "Foo") ; procedure identifier
(BYVAL
(IDENTLIST "bar" "baz") ; formal parameter identifiers
(ARRAYOF "Bam")) ; open array formal type
(EMPTY))) ; no return type
An open array formal type node is created using the AST API call
ast_node = m2c_ast_new_node(AST_ARRAYOF, base_type_ident_node, NULL);
A variadic formal type node encodes a variadic formal type for one or more formal parameters of a procedure signature.
PROCEDURE Foo ( bar, baz : ARGLIST OF Bam );
is encoded as
(PROCDECL
(PSIG
(IDENT "Foo") ; procedure identifier
(BYVAL
(IDENTLIST "bar" "baz") ; formal parameter identifiers
(ARGLIST "Bam")) ; list element type identifier
(EMPTY))) ; no return type
A variadic formal type node is created using the AST API call
ast_node = m2c_ast_new_node(AST_ARGLIST, base_type_ident_node, NULL);
A casting formal type node encodes a casting formal type for one or more formal parameters of a procedure signature.
PROCEDURE Foo ( barPtr : CAST ADDRESS );
is encoded as
(PROCDECL
(PSIG
(IDENT "Foo") ; procedure identifier
(BYVAL
(IDENT "barPtr") ; formal parameter identifier
(CAST "ADDRESS")) ; casting type identifier
(EMPTY))) ; no return type
and
PROCEDURE Baz ( bam : CAST OCTETSEQ );
is encoded as
(PROCDECL
(PSIG
(IDENT "Baz") ; procedure identifier
(BYVAL
(IDENT "bam") ; formal type identifier
(CAST "OCTETSEQ")) ; casting type identifier
(EMPTY))) ; no return type
A casting formal type node is created using the AST API call
ast_node = m2c_ast_new_node(AST_CAST, base_type_ident_node, NULL);
An alias type node encodes the type constructor for an alias type.
TYPE Foo = ALIAS OF BAR;
is encoded as
(TYPEDEF (IDENT "Foo") ; alias type identifier
(ALIAS (IDENT "Bar")) ; base type identifier
An alias type node is created using the AST API call
ast_node = m2c_ast_new_node(AST_ALIAS, base_type_node, NULL);
A subrange type node encodes the type constructor for a subrange type.
TYPE DecDigit = [0 .. 9] OF CARDINAL;
is encoded as
(TYPEDEF (IDENT "DecDigit") ; subrange type identifier
(SUBR
(IDENT "CARDINAL") ; base type identifier
(RANGE (INTVAL 0) (INTVAL 9)))) ; value range
A subrange type node is created using the AST API call
ast_node = m2c_ast_new_node(AST_SUBR,
base_type_node, range_node, NULL);
TO DO
An enumeration type node encodes the type constructor for an enumeration type.
TYPE BaseColour = ( Red, Green, Blue );
TYPE MoreColour = ( +BaseColour, Orange, Yellow, Purple );
is encoded as
(TYPEDEF (IDENT "BaseColour") ; enumeration type identifier
(EMPTY) ; no base type
(IDENTLIST "Red" "Green" "Blue")) ; enumerated value identifiers
(TYPEDEF (IDENT "MoreColour") ; enumeration type identifier
(IDENT "BaseColour") ; base type identifier
(IDENTLIST "Orange" "Yellow" "Purple")) ; enumerated value identifiers
An enumeration type node is created using the AST API call
ast_node = m2c_ast_new_node(AST_ENUM,
base_type_node, value_list_node, NULL);
A set type node encodes the type constructor for a set type.
TYPE ColourSet = SET OF BaseColour;
is encoded as
(TYPEDEF (IDENT "ColourSet")
(SET (IDENT "BaseColour"))
A set type node is created using the AST API call
ast_node = m2c_ast_new_node(AST_SET, base_type_node, NULL);
An array type node encodes the type constructor for an array type.
TYPE Str80 = ARRAY 80 OF CHAR;
is encoded as
(TYPEDEF (IDENT "Str80")
(ARRAY (IDENT "CHAR") (INTVAL 80))
An array type node is created using the AST API call
ast_node = m2c_ast_new_node(AST_ARRAY,
base_type_node, capacity_node, NULL);
A record type node encodes the type constructor for a record type.
TYPE Foo = RECORD
bar : Bar;
baz : Baz
END;
is encoded as
(TYPEDEF (IDENT "Foo")
(RECORD
(EMPTY) ; no base type
(FIELD-LIST-SEQ
(VARDEF (IDENT "bar") (IDENT "Bar") ; field list definition
(VARDEF (IDENT "baz") (IDENT "Baz"))))) ; field list definition
and
TYPE Root = RECORD (NIL)
foo : Foo;
END;
TYPE Extension = RECORD (Root)
bar : Bar;
baz, bam : Baz
END;
is encoded as
(TYPEDEF (IDENT "Root")
(RECORD
(IDENT "NIL") ; root type indicator
(FIELD-LIST-SEQ
(VARDEF (IDENT "foo") (IDENT "Foo")))) ; field list definition
and
(TYPEDEF (IDENT "Extension")
(RECORD
(IDENT "Root") ; base type identifier
(FIELD-LIST-SEQ
(VARDEF (IDENT "bar") (IDENT "Bar") ; field list definition
(VARDEF (IDENTLIST "baz" "bam") (IDENT "Baz"))))) ; field list definition
A record type node is created using the AST API call
ast_node = m2c_ast_new_node(AST_RECORD,
base_type_node, field_list_seq_node, NULL);
A field list sequence node encodes one or more field list definitions within a record type.
A field list sequence node is created using the AST API call
ast_node = m2c_ast_new_list_node(AST_FIELDLISTSEQ, field_list_seq);
where field_list_seq
is a
FIFO API created object of type fifo_t
and the list elements are AST nodes of type m2c_astnode_t
.
A variable definition node is used to encode a field list definition within a field list sequence node.
See Variable Definition for details.
A pointer type node encodes the type constructor for a pointer type.
TYPE Foo = POINTER TO Bar;
is encoded as
(TYPEDEF (IDENT "Foo")
(POINTER (IDENT "Bar"))
A pointer type node is created using the AST API call
ast_node = m2c_ast_new_node(AST_POINTER, target_type_node, NULL);
A type declaration node encodes the type constructor for an opaque type.
See Type Declaration for details.
A procedure type node encodes the type constructor for a procedure type.
TYPE Foo = PROCEDURE ( ... ) : Bam ;
is encoded as
(TYPEDEF (IDENT "Foo")
(PROC-TYPE ( ... ) (IDENT "Bam"))
A procedure type node is created using the AST API call
ast_node = m2c_ast_new_node(AST_PROCTYPE,
formal_type_list_node, ret_type_node, NULL);
A statement sequence node encodes one or more statements.
foo := 0;
bar := 1;
counter++;
is encoded as
(STMTSEQ
(ASSIGN (IDENT "foo") (INTVAL 0))
(ASSIGN (IDENT "bar") (INTVAL 1))
(INCR (IDENT "counter")))
A statement sequence node is created using the AST API call
ast_node = m2c_ast_new_list_node(AST_STMTSEQ, stmt_list);
where stmt_list
is a
FIFO API created object of type fifo_t
and the list elements are AST nodes of type m2c_astnode_t
.
An assignment statement node encodes an assignment statement.
foo := bar;
is encoded as
(ASSIGN (IDENT "foo") (IDENT "bar"))
An assignment statement node is created using the AST API call
ast_node = m2c_ast_new_node(AST_ASSIGN,
target_designator_node, expr_node, NULL);
An increment statement node encodes an increment statement.
counter++;
is encoded as
(INCR (IDENT "counter"))
An increment statement node is created using the AST API call
ast_node = m2c_ast_new_node(AST_INCR, designator_node, NULL);
A decrement statement node encodes a decrement statement.
counter--;
is encoded as
(DECR (IDENT "counter"))
A decrement statement node is created using the AST API call
ast_node = m2c_ast_new_node(AST_DECR, designator_node, NULL);
A procedure call node encodes a procedure call.
Foo;
is encoded as
(PCALL (IDENT "Foo") (EMPTY))
and
Bar(baz);
is encoded as
(PCALL (IDENT "Bar") (IDENT "baz"))
A procedure call node is created using the AST API call
ast_node = m2c_ast_new_node(AST_PCALL,
designator_node, arguments_node, NULL);
A return statement node encodes a return statement.
RETURN foo;
is encoded as
(RETURN (IDENT "foo"))
A return statement node is created using the AST API call
ast_node = m2c_ast_new_node(AST_RETURN, expr_node, NULL);
A new statement node encodes a new statement.
NEW foo;
is encoded as
(NEW (IDENT "foo"))
A new statement node is created using the AST API call
ast_node = m2c_ast_new_node(AST_NEW, designator_node, NULL);
A new arglist statement node encodes a new statement with initialisation arguments.
NEW foo := { bar, baz, bam };
is encoded as
(NEWARG (IDENT "foo") (STRUCT "bar" "baz" "bam"))
A new arglist statement node is created using the AST API call
ast_node = m2c_ast_new_node(AST_NEWARG,
designator_node, designator_or_expr_node, NULL);
A new capacity statement node encodes a new statement with capacity argument.
NEW foo CAPACITY 1000;
is encoded as
(NEWCAP (IDENT "foo") (INTVAL 1000))
A new capacity statement node is created using the AST API call
ast_node = m2c_ast_new_node(AST_NEWCAP,
designator_node, expr_node, NULL);
A retain statement node encodes a retain statement.
RETAIN foo;
is encoded as
(RETAIN (IDENT "foo"))
A retain statement node is created using the AST API call
ast_node = m2c_ast_new_node(AST_RETAIN, designator_node, NULL);
A release statement node encodes a release statement.
RELEASE foo;
is encoded as
(RELEASE (IDENT "foo"))
A release statement node is created using the AST API call
ast_node = m2c_ast_new_node(AST_RELEASE, designator_node, NULL);
An if statement node encodes an if statement.
IF n > 0 THEN
n := 1
END;
is encoded as
(IF
(GT (IDENT "n") (INTVAL 0)) ; condition expression node
(ASSIGN (IDENT "n") (INTVAL 1)) ; if branch statement node
(EMPTY) ; no elsif branches
(EMPTY)) ; no else branch
and
IF n > 0 THEN
n := 1
ELSE
n := 0
END;
is encoded as
(IF
(GT (IDENT "n") (INTVAL 0)) ; condition expression node
(ASSIGN (IDENT "n") (INTVAL 1)) ; if branch statement node
(EMPTY) ; no elsif branches
(ASSIGN (IDENT "n") (INTVAL 0))) ; else branch statement node
An if statement node is created using the AST API call
ast_node = m2c_ast_new_node(AST_IF,
expr_node, stmt_seq_node, elsif_seq_node, else_stmt_seq_node, NULL);
An elsif sequence node encodes one or more elsif branch nodes.
IF n > 999 THEN
exp := 3
ELSIF n > 99 THEN
exp := 2
ELSIF n > 9 THEN
exp := 1
ELSE
exp := 0
END;
is encoded as
(IF (GT (IDENT "n") (INTVAL 999)) ; if branch
(ASSIGN (IDENT "exp") (INTVAL 3))
(ELSIFSEQ
(ELSIF (GT (IDENT "n") (INTVAL 99)) ; first elsif branch
(ASSIGN (IDENT "exp") (INTVAL 2))
(ELSIF (GT (IDENT "n") (INTVAL 9)) ; second elsif branch
(ASSIGN (IDENT "exp") (INTVAL 1)))
(ASSIGN (IDENT "exp") (INTVAL 0))) ; else branch
An elsif sequence node is created using the AST API call
ast_node = m2c_ast_new_list_node(AST_ELSIFSEQ, elsif_node_list);
where elsif_node_list
is a
FIFO API created object of type fifo_t
and the list elements are AST nodes of type m2c_astnode_t
.
An elsif branch node encodes an elsif branch.
IF n > 0 THEN
n := 1
ELSIF n < 0 THEN
n := -1
END;
is encoded as
(IF (GT (IDENT "n") (INTVAL 0)) ; if branch
(ASSIGN (IDENT "n") (INTVAL 1))
(ELSIF (LT (IDENT "n") (INTVAL 0)) ; elsif branch
(ASSIGN (IDENT "n") (NEG (INTVAL 1))))
(EMPTY)) ; no else branch
An elsif statement node is created using the AST API call
ast_node = m2c_ast_new_node(AST_ELSIF,
expr_node, stmt_seq_node, NULL);
TO DO
A loop statement node encodes a loop statement.
LOOP
Foo(bar)
END;
is encoded as
(LOOP (PCALL (IDENT "Foo") (IDENT "bar")))
A loop statement node is created using the AST API call
ast_node = m2c_ast_new_node(AST_LOOP, stmt_seq_node, NULL);
Copyright (C) 2023 Modula-2 Software Foundation