-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmoc.Mod
More file actions
124 lines (115 loc) · 2.91 KB
/
moc.Mod
File metadata and controls
124 lines (115 loc) · 2.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
MODULE Moc;
IMPORT Out, Args, Strings, Machine, Parser, Scanner, Traverser, Table, Tree, Linker;
CONST
version = '1.0.0-alpha.1';
PROCEDURE Welcome;
BEGIN
Out.String('Mac Oberon Compiler version ');
Out.String(version); Out.Ln;
Out.String('Copyright (c) 2025');
Out.String(' by Arthur Yefimov.'); Out.Ln
END Welcome;
PROCEDURE Usage;
VAR s: ARRAY 256 OF CHAR;
BEGIN
Out.String('Usage:'); Out.Ln; Args.Get(0, s);
Out.String(' '); Out.String(s);
Out.String(' {parameter} sourceFile'); Out.Ln; Out.Ln;
Out.String('Parameters:'); Out.Ln;
Out.String(' -o outputFile Specify an executable file name'); Out.Ln;
Out.String(' --debug Enable debug output'); Out.Ln; Out.Ln
END Usage;
(** Finds period and truncates the string there. Puts the result in exe.
'Module.Mod' -> 'Module'.
If period is not found, the result is an empty string. *)
PROCEDURE SourceToExeFname(fname: ARRAY OF CHAR; VAR exe: ARRAY OF CHAR);
VAR i: INTEGER;
BEGIN
i := 0;
WHILE (fname[i] # 0X) & (fname[i] # '.') DO
exe[i] := fname[i];
INC(i)
END;
IF fname[i] = 0X THEN i := 0 END;
exe[i] := 0X
END SourceToExeFname;
PROCEDURE ParseArgs(VAR mainFname, exeFname: ARRAY OF CHAR);
VAR i, count: INTEGER;
s: ARRAY 256 OF CHAR;
ok: BOOLEAN;
BEGIN
ok := TRUE;
mainFname := '';
exeFname := '';
i := 1;
count := Args.Count();
WHILE i <= count DO
Args.Get(i, s);
IF s = '-o' THEN
Args.Get(i + 1, exeFname);
INC(i)
ELSIF s = '--debug' THEN
Machine.SetDebug(TRUE)
ELSIF mainFname = '' THEN
Strings.Copy(s, mainFname)
ELSE
ok := FALSE
END;
INC(i)
END;
IF ~ok THEN
Out.String('Error while parsing command line arguments. ');
Usage
ELSIF exeFname = '' THEN
SourceToExeFname(mainFname, exeFname)
END
END ParseArgs;
PROCEDURE Run(mainFname, exeFname: ARRAY OF CHAR);
VAR module: Tree.Node;
BEGIN
IF ~Machine.OpenSourceFile(mainFname) THEN
Out.String('Could not open source file "');
Out.String(mainFname); Out.String('".'); Out.Ln
ELSE
module := Parser.Parse();
IF ~Machine.hadErrors THEN
Machine.BackendPhase;
IF Machine.debugFrontend THEN
Out.String('--- Abstract Syntax Tree ---'); Out.Ln;
Tree.Print(module, 0);
Out.String('--- Symbol Table ---'); Out.Ln;
Table.Print(Table.topScope, 0)
END;
Traverser.SetAddressesAndSizes(Table.topScope);
IF ~Machine.hadErrors THEN
Traverser.Traverse(module);
IF ~Machine.hadErrors THEN
Linker.Link(exeFname)
END
END
END
END
END Run;
PROCEDURE PraseAndRun;
VAR
mainFname, exeFname: ARRAY 256 OF CHAR;
BEGIN
ParseArgs(mainFname, exeFname);
IF mainFname # '' THEN
Run(mainFname, exeFname)
ELSE
Out.String('No file specified.'); Out.Ln
END
END PraseAndRun;
PROCEDURE Do*;
BEGIN
IF Args.Count() = 0 THEN
Welcome;
Usage
ELSE
PraseAndRun
END
END Do;
BEGIN
Do
END Moc.