Artifact 442c0afd591f3c6aa12c9e1f6777562cd5fd25d4
1 /**
2 * Authors: k.inaba
3 * License: NYSL 0.9982 http://www.kmonos.net/nysl/
4 *
5 * Error Information for Polemy Programming Language
6 */
7 module polemy.failure;
8 import polemy._common;
9
10 /// Represents a position in source codes
11
12 alias immutable(LexPosition_t) LexPosition;
13
14 /// Represents a position in source codes
15
16 class LexPosition_t
17 {
18 immutable string filename; /// name of the source file
19 immutable int lineno; /// 1-origin
20 immutable int column; /// 1-origin
21
22 mixin SimpleClass;
23 override string toString() const
24 { return sprintf!("%s:%d:%d")(filename, lineno, column); }
25 static LexPosition dummy;
26 static this(){ dummy = new LexPosition("<nowhere>",0,0); }
27 }
28
29 unittest
30 {
31 auto p = new LexPosition("hello.cpp", 123, 45);
32
33 assert_eq( p.filename, "hello.cpp" );
34 assert_eq( p.lineno, 123 );
35 assert_eq( p.column, 45 );
36 assert_eq( text(p), "hello.cpp:123:45" );
37
38 assert( !__traits(compiles, new LexPosition) );
39 assert( !__traits(compiles, p.filename="foo") );
40 assert( !__traits(compiles, p.lineno =789) );
41 assert( !__traits(compiles, p.column =222) );
42
43 auto q = new LexPosition("hello.cpp", 123, 46);
44 assert_lt( p, q );
45 assert_ne( p, q );
46 }
47
48 /*mixin*/
49 template ExceptionWithPosition()
50 {
51 LexPosition pos;
52 this( LexPosition pos, string msg, string file=null, size_t line=0, Throwable next=null )
53 {
54 string fullmsg = pos is null ? sprintf!("\n[??] %s")(msg)
55 : sprintf!("\n[%s] %s")(pos, msg);
56 foreach_reverse(i,_; callstack_pos)
57 {
58 LexPosition p = callstack_pos[i];
59 string m = callstack_msg[i];
60 fullmsg ~= p is null ? sprintf!("\n[??] %s")(m)
61 : sprintf!("\n[%s] %s")(p, m);
62 }
63 super(fullmsg, file, line, next);
64 this.pos = pos;
65 }
66 this( string msg, string file=null, size_t line=0, Throwable next=null )
67 {
68 this(null, msg, file, line, next);
69 }
70 }
71
72 class UnexpectedEOF : Exception { mixin ExceptionWithPosition; } /// EOF during lexing/parsing
73 class LexException : Exception { mixin ExceptionWithPosition; } /// Lexer errors
74 class ParseException : Exception { mixin ExceptionWithPosition; } /// Parser errors
75 class RuntimeException : Exception { mixin ExceptionWithPosition; } /// Evaluator errors
76
77 /// Per-thread call stack management.
78 /// This scoped class's ctor&dtor maintain the callstack.
79 /// TODO: make it "per-evaluator" !!!!!!!!!!!
80
81 scope class PushCallStack
82 {
83 this(LexPosition pos, string msg) { callstackEnterFunction(pos,msg); }
84 ~this() { callstackLeaveFunction(); }
85 }
86
87 LexPosition[] callstack_pos;
88 string[] callstack_msg;
89
90 private void callstackEnterFunction(LexPosition pos, string msg)
91 {
92 callstack_pos ~= pos;
93 callstack_msg ~= msg;
94 }
95
96 private void callstackLeaveFunction()
97 {
98 callstack_pos.length -= 1;
99 callstack_msg.length -= 1;
100 }