-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathExceptions.cpp
More file actions
145 lines (127 loc) · 3.89 KB
/
Exceptions.cpp
File metadata and controls
145 lines (127 loc) · 3.89 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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/**
* Copyright 2010 by Benjamin J. Land (a.k.a. BenLand100)
*
* This file is part of CPascal.
*
* CPascal is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CPascal is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CPascal. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Exceptions.h"
#include <cstdio>
#include <cstring>
#include <math.h>
int InterpEx::getType(int cause) {
return (cause / 100) * 100;
}
InterpEx::InterpEx(int cause_impl) : cause(cause_impl) {
}
InterpEx::~InterpEx() throw() {
}
inline int postoline(char *ppg, int pos) {
int end = strlen(ppg);
end = end < pos ? end : pos;
int lines = 1;
for (int i = 0; i <= end; i++)
if (ppg[i] == '\n')
lines++;
return lines;
}
void InterpEx::getData(char* ppg, int &line, int &pos, const char* &err) {
line = postoline(ppg,*trace.begin());
pos = 0;
err = what();
}
void InterpEx::addTrace(int pos) {
trace.push_back(pos);
}
int InterpEx::getType() {
return getType(cause);
}
int InterpEx::getCause() {
return cause;
}
std::list<int> InterpEx::getTrace() {
return trace;
}
void InterpEx::printStackTrace(char *ppg) {
std::list<int>::iterator trace_iter = trace.begin();
std::list<int>::iterator trace_end = trace.end();
printf("Exception at line %i: %s\n", postoline(ppg,*trace_iter), what());
trace_iter++;
while (trace_iter != trace_end) {
printf("\ttrace: %i\n",postoline(ppg,*trace_iter));
trace_iter++;
}
}
const char* InterpEx::what() const throw() {
switch (cause) {
case E_DIV_ZERO:
return "Divide by zero";
case E_NOT_INTEGER:
return "Integer expected";
case E_NOT_REAL:
return "Real expected";
case E_NOT_CHAR:
return "Char expected";
case E_NOT_STRING:
return "String expected";
case E_NOT_BOOLEAN:
return "Boolean expected";
case E_NOT_RECORD:
return "Record expected";
case E_NOT_ARRAY:
return "Array expected";
case E_NOT_POINTER:
return "Pointer expected";
case E_NULL_VAL:
return "Null value ";
case E_NON_NUMERIC:
return "Numeric value expected";
case E_INDEX_BOUNDS:
return "Index out of bounds";
case E_NO_FIELD:
return "No such field";
case E_UNRESOLVABLE:
return "Symbol undefined";
case E_STATIC_ARRAY:
return "Array is not dynamic";
case E_NOT_METHOD:
return "Cannot invoke a non-method";
case E_WRONG_NUM_ARG:
return "Wrong number of arguments to method";
case E_REF_TYPE:
return "Refrence type not defined";
case E_INVALID_CHAR:
return "Invalid character in script";
case E_EOF:
return "Reached end of file";
case E_BAD_PRECOMP:
return "Unknown precompiler directive";
case E_EXPECTED:
return "Something was expected and not found";
case E_NO_EQUIV_VAL:
return "Conversion to/from native not defined";
default:
return "Unknown error!";
}
}
ParserEx::ParserEx(char* error) : InterpEx(E_EXPECTED) {
this->error = new char[strlen(error)+1];
strcpy((char*)this->error,error);
}
ParserEx::~ParserEx() throw() {
delete error;
}
const char* ParserEx::what() const throw() {
return error;
}