Skip to content

Commit 27ac9e7

Browse files
committed
refactor(Errors): encapsulate and cleanup error logging
1 parent b374509 commit 27ac9e7

5 files changed

Lines changed: 45 additions & 37 deletions

File tree

src/TinyCompiler/Compiler.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System.Collections.Generic;
1+
using System.Collections.Generic;
22

33
namespace TinyCompiler
44
{
@@ -9,23 +9,23 @@ public static class Compiler
99

1010
public static void Compile(string sourceCode)
1111
{
12-
Errors.Error_List.Clear();
12+
Errors.Clear();
1313
TokenStream.Clear();
1414
treeRoot = null;
1515

1616
//Scanner
1717
Scanner scanner = new Scanner(sourceCode);
1818
TokenStream = scanner.Scan();
1919
if (Errors.HasError()) {
20-
Errors.Error_List.Add($"Compilation failed, found {Errors.Error_List.Count} error{(Errors.Error_List.Count == 1 ? "" : "s")}.");
20+
Errors.ReportError($"========== compile: {Errors.Count()} lex error ==========");
2121
return;
2222
}
2323

2424
//Parser
2525
Parser parser = new Parser(TokenStream);
2626
treeRoot = parser.Parse();
2727
if (Errors.HasError()) {
28-
Errors.Error_List.Add($"Compilation failed, found {Errors.Error_List.Count} error{(Errors.Error_List.Count == 1 ? "" : "s")}.");
28+
Errors.ReportError($"========== compile: {Errors.Count()} parse error ==========");
2929
return;
3030
}
3131

src/TinyCompiler/Errors.cs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,21 @@ namespace TinyCompiler
55
{
66
public static class Errors
77
{
8-
public static List<string> Error_List = new List<string>();
8+
private static readonly List<string> ErrorList = new List<string>();
99

10-
public static void Add(int lineNumber, string msg)
10+
public static List<string> GetAll() => ErrorList;
11+
12+
public static int Count() => ErrorList.Count();
13+
14+
public static bool HasError() => ErrorList.Any();
15+
16+
public static void Clear() => ErrorList.Clear();
17+
18+
public static void ReportError(string msg) => ErrorList.Add(msg);
19+
20+
public static void ReportError(int lineNumber, string msg)
1121
{
12-
Error_List.Add($"[Line {lineNumber}]: {msg}.");
22+
ReportError($"line:{lineNumber}: error: {msg}");
1323
}
14-
15-
public static bool HasError() => Error_List.Any();
1624
}
1725
}

src/TinyCompiler/Parser.cs

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,17 @@ private Node Program() {
5858
// Add main function
5959
if (IsAtEnd())
6060
{
61-
Error(PreviousToken(), "Expected main function.");
61+
Error(PreviousToken(), "expected main function");
6262
}
6363
else
6464
{
6565
n.Children.Add(Func());
6666
}
6767
}
68-
catch (ParseError) { }
68+
catch (ParseError)
69+
{
70+
Errors.ReportError("parser: found fatal error... stopping");
71+
}
6972

7073
return n;
7174
}
@@ -84,7 +87,7 @@ private Node FuncDecl() {
8487

8588
n.Children.Add(Datatype());
8689
n.Children.Add(Consume(TokenClass.Identifier));
87-
n.Children.Add(Consume(TokenClass.LeftParen, "Expect '(' after function name."));
90+
n.Children.Add(Consume(TokenClass.LeftParen, "expected '(' after function name"));
8891

8992
Node parameters = new Node("Parameters");
9093
while (!Check(TokenClass.RightParen))
@@ -93,12 +96,12 @@ private Node FuncDecl() {
9396

9497
if (!Check(TokenClass.RightParen))
9598
{
96-
parameters.Children.Add(Consume(TokenClass.Comma, "Expect ',' between parameters."));
99+
parameters.Children.Add(Consume(TokenClass.Comma, "expected ',' between parameters"));
97100
}
98101
}
99102
n.Children.Add(parameters);
100103

101-
n.Children.Add(Consume(TokenClass.RightParen, "Expect ')' after parameters."));
104+
n.Children.Add(Consume(TokenClass.RightParen, "expected ')' after parameters"));
102105

103106
return n;
104107
}
@@ -107,27 +110,27 @@ private Node Param() {
107110
Node n = new Node("Parameter");
108111

109112
n.Children.Add(Datatype());
110-
n.Children.Add(Consume(TokenClass.Identifier, "Expect parameter name."));
113+
n.Children.Add(Consume(TokenClass.Identifier, "expected parameter name"));
111114

112115
return n;
113116
}
114117

115118
private Node FuncBody() {
116119
Node n = new Node("Function Body");
117120

118-
n.Children.Add(Consume(TokenClass.LeftBrace, "Expect '{' before function body."));
121+
n.Children.Add(Consume(TokenClass.LeftBrace, "expected '{' before function body"));
119122
n.Children.Add(Stmts());
120123
n.Children.Add(RetStmt());
121-
n.Children.Add(Consume(TokenClass.RightBrace, "Expect '}' after function body."));
124+
n.Children.Add(Consume(TokenClass.RightBrace, "expected '}' after function body"));
122125

123126
return n;
124127
}
125128

126129
private Node FuncCall() {
127130
Node n = new Node("Function Call");
128131

129-
n.Children.Add(Consume(TokenClass.Identifier, "Expect function name."));
130-
n.Children.Add(Consume(TokenClass.LeftParen, "Expect '(' after function name."));
132+
n.Children.Add(Consume(TokenClass.Identifier, "expected function name"));
133+
n.Children.Add(Consume(TokenClass.LeftParen, "expected '(' after function name"));
131134

132135
Node args = new Node("Arguments");
133136
while (!Check(TokenClass.RightParen))
@@ -136,12 +139,12 @@ private Node FuncCall() {
136139

137140
if (!Check(TokenClass.RightParen))
138141
{
139-
args.Children.Add(Consume(TokenClass.Comma, "Expect ',' between arguments."));
142+
args.Children.Add(Consume(TokenClass.Comma, "expected ',' between arguments"));
140143
}
141144
}
142145
n.Children.Add(args);
143146

144-
n.Children.Add(Consume(TokenClass.RightParen, "Expect ')' after arguments."));
147+
n.Children.Add(Consume(TokenClass.RightParen, "expected ')' after arguments"));
145148

146149
return n;
147150
}
@@ -161,7 +164,7 @@ private Node Datatype() {
161164
return n;
162165
}
163166

164-
throw Error(Peek(), "Expected 'int', 'float', or 'string'.");
167+
throw Error(Peek(), "expected 'int', 'float', or 'string'");
165168
}
166169

167170
private Node Stmt() {
@@ -198,7 +201,7 @@ private Node Stmt() {
198201
n.Children.Add(Consume(TokenClass.Semicolon));
199202
break;
200203
default:
201-
throw Error(Peek(), "Expect statement.");
204+
throw Error(Peek(), "expected statement");
202205
break;
203206
}
204207

@@ -358,7 +361,7 @@ private Node Cond() {
358361
}
359362
else
360363
{
361-
Error(Peek(), "Expected conditional operator.");
364+
Error(Peek(), "expected '<', '>', '<>', or '=' operator");
362365
}
363366
n.Children.Add(Expr());
364367

@@ -470,7 +473,7 @@ private Node Factor()
470473
}
471474
else
472475
{
473-
Error(Peek(), "Expected number, string, identifier, or (expression).");
476+
Error(Peek(), "expected number, string, identifier, or (expression)");
474477
}
475478

476479
return n;
@@ -595,18 +598,18 @@ private Node Consume(TokenClass type, string message)
595598

596599
private Node Consume(TokenClass type)
597600
{
598-
return Consume(type, $"Expected '{type.ToString().ToLowerInvariant()}'.");
601+
return Consume(type, $"expected '{type.ToString().ToLowerInvariant()}'");
599602
}
600603

601604
private ParseError Error(Token token, string message)
602605
{
603606
if (IsAtEnd())
604607
{
605-
Errors.Error_List.Add($"[line {token.line}] Error at end: {message}");
608+
Errors.ReportError(token.line, $"at end: {message}");
606609
}
607610
else
608611
{
609-
Errors.Error_List.Add($"[line {token.line}] Error: at '{token.lex}': {message}");
612+
Errors.ReportError(token.line, $"at '{token.lex}': {message}");
610613
}
611614

612615
return new ParseError();

src/TinyCompiler/Scanner.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ public List<Token> Scan()
131131
}
132132
else
133133
{
134-
Errors.Add(_linenumber, $"unexpected lexeme '{c}'");
134+
Errors.ReportError(_linenumber, $"unexpected lexeme '{c}'");
135135
}
136136
break;
137137
}
@@ -163,7 +163,7 @@ private void ReadNumber()
163163
Read();
164164
} else if (char.IsLetter(Peek())) {
165165
Read();
166-
Errors.Add(_linenumber, "illegal identifier");
166+
Errors.ReportError(_linenumber, "illegal identifier");
167167
return;
168168
}
169169

@@ -188,7 +188,7 @@ private void ReadString()
188188
if (Match('"'))
189189
AddToken(TokenClass.StringLiteral);
190190
else
191-
Errors.Add(_linenumber, "unterminated string, expected '\"'");
191+
Errors.ReportError(_linenumber, "unterminated string, expected '\"'");
192192
}
193193

194194
private void ReadComment()
@@ -209,7 +209,7 @@ private void ReadComment()
209209
if (Peek() == '/')
210210
Read();
211211
else
212-
Errors.Add(_linenumber, "unterminated comment, expected '*/'");
212+
Errors.ReportError(_linenumber, "unterminated comment, expected '*/'");
213213
}
214214

215215
private void AddToken(TokenClass type)

src/TinyCompiler/WindowForm.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,7 @@ private void PopulateTokensTable()
5858
private void PrintErrors()
5959
{
6060
tfErrors.Clear();
61-
foreach (var error in Errors.Error_List)
62-
{
63-
tfErrors.Text += error + "\r\n";
64-
}
61+
tfErrors.Text = string.Join("\r\n", Errors.GetAll());
6562
}
6663

6764
private void PopulateParseTree()
@@ -80,7 +77,7 @@ private void btnClear_Click(object sender, System.EventArgs e)
8077

8178
// Reset Global Data
8279
Compiler.TokenStream.Clear();
83-
Errors.Error_List.Clear();
80+
Errors.Clear();
8481
}
8582

8683
private static TreeNode PrintParaseTree(Node root)

0 commit comments

Comments
 (0)