3464a035ec 2010-11-20 kinaba: /** 3464a035ec 2010-11-20 kinaba: * Authors: k.inaba 3464a035ec 2010-11-20 kinaba: * License: NYSL 0.9982 http://www.kmonos.net/nysl/ 3464a035ec 2010-11-20 kinaba: * 3464a035ec 2010-11-20 kinaba: * Error Information for Polemy Programming Language 3464a035ec 2010-11-20 kinaba: */ 3464a035ec 2010-11-20 kinaba: module polemy.failure; 3464a035ec 2010-11-20 kinaba: import polemy._common; 3464a035ec 2010-11-20 kinaba: 3464a035ec 2010-11-20 kinaba: /// Represents a position in source codes 3464a035ec 2010-11-20 kinaba: 3995a5eb6a 2010-11-21 kinaba: alias immutable(LexPosition_t) LexPosition; 3995a5eb6a 2010-11-21 kinaba: 3995a5eb6a 2010-11-21 kinaba: /// Represents a position in source codes 3995a5eb6a 2010-11-21 kinaba: 2bdfb8a182 2010-11-21 kinaba: class LexPosition_t 3464a035ec 2010-11-20 kinaba: { 3464a035ec 2010-11-20 kinaba: immutable string filename; /// name of the source file 3464a035ec 2010-11-20 kinaba: immutable int lineno; /// 1-origin 3464a035ec 2010-11-20 kinaba: immutable int column; /// 1-origin 3464a035ec 2010-11-20 kinaba: 3464a035ec 2010-11-20 kinaba: mixin SimpleClass; 3464a035ec 2010-11-20 kinaba: override string toString() const 2134cd44cc 2010-11-23 kinaba: { return sprintf!("%s:%d:%d")(filename, lineno, column); } 2bdfb8a182 2010-11-21 kinaba: static LexPosition dummy; 2bdfb8a182 2010-11-21 kinaba: static this(){ dummy = new LexPosition("<unnamed>",0,0); } 3464a035ec 2010-11-20 kinaba: } 3464a035ec 2010-11-20 kinaba: 3464a035ec 2010-11-20 kinaba: unittest 3464a035ec 2010-11-20 kinaba: { 3464a035ec 2010-11-20 kinaba: auto p = new LexPosition("hello.cpp", 123, 45); 3464a035ec 2010-11-20 kinaba: 3464a035ec 2010-11-20 kinaba: assert_eq( p.filename, "hello.cpp" ); 3464a035ec 2010-11-20 kinaba: assert_eq( p.lineno, 123 ); 3464a035ec 2010-11-20 kinaba: assert_eq( p.column, 45 ); 3464a035ec 2010-11-20 kinaba: assert_eq( text(p), "hello.cpp:123:45" ); 3464a035ec 2010-11-20 kinaba: 3464a035ec 2010-11-20 kinaba: assert( !__traits(compiles, new LexPosition) ); 3464a035ec 2010-11-20 kinaba: assert( !__traits(compiles, p.filename="foo") ); 3464a035ec 2010-11-20 kinaba: assert( !__traits(compiles, p.lineno =789) ); 3464a035ec 2010-11-20 kinaba: assert( !__traits(compiles, p.column =222) ); 3464a035ec 2010-11-20 kinaba: 3464a035ec 2010-11-20 kinaba: auto q = new LexPosition("hello.cpp", 123, 46); 3464a035ec 2010-11-20 kinaba: assert_lt( p, q ); 3464a035ec 2010-11-20 kinaba: assert_ne( p, q ); 3464a035ec 2010-11-20 kinaba: } 3464a035ec 2010-11-20 kinaba: 3464a035ec 2010-11-20 kinaba: /*mixin*/ 3464a035ec 2010-11-20 kinaba: template ExceptionWithPosition() 3464a035ec 2010-11-20 kinaba: { 2bdfb8a182 2010-11-21 kinaba: LexPosition pos; 2bdfb8a182 2010-11-21 kinaba: this( LexPosition pos, string msg, string file=null, size_t line=0, Throwable next=null ) 3464a035ec 2010-11-20 kinaba: { 2134cd44cc 2010-11-23 kinaba: string fullmsg = pos is null ? sprintf!("\n[??] %s")(msg) 2134cd44cc 2010-11-23 kinaba: : sprintf!("\n[%s] %s")(pos, msg); 2134cd44cc 2010-11-23 kinaba: for(int i=0; i<callstack_pos.length || i<callstack_msg.length; ++i) 2134cd44cc 2010-11-23 kinaba: { 2134cd44cc 2010-11-23 kinaba: LexPosition p = (i<callstack_pos.length ? callstack_pos[i] : null); 2134cd44cc 2010-11-23 kinaba: string m = (i<callstack_msg.length ? callstack_msg[i] : null); 2134cd44cc 2010-11-23 kinaba: fullmsg ~= p is null ? sprintf!("\n[??] %s")(m) 2134cd44cc 2010-11-23 kinaba: : sprintf!("\n[%s] %s")(p, m); 2134cd44cc 2010-11-23 kinaba: } 2134cd44cc 2010-11-23 kinaba: super(fullmsg, file, line, next); 3464a035ec 2010-11-20 kinaba: this.pos = pos; 2134cd44cc 2010-11-23 kinaba: } 2134cd44cc 2010-11-23 kinaba: this( string msg, string file=null, size_t line=0, Throwable next=null ) 2134cd44cc 2010-11-23 kinaba: { 2134cd44cc 2010-11-23 kinaba: this(null, msg, file, line, next); 3464a035ec 2010-11-20 kinaba: } 3464a035ec 2010-11-20 kinaba: } 3464a035ec 2010-11-20 kinaba: 2134cd44cc 2010-11-23 kinaba: class UnexpectedEOF : Exception { mixin ExceptionWithPosition; } /// EOF during lexing/parsing 2134cd44cc 2010-11-23 kinaba: class LexException : Exception { mixin ExceptionWithPosition; } /// Lexer errors 2134cd44cc 2010-11-23 kinaba: class ParseException : Exception { mixin ExceptionWithPosition; } /// Parser errors 3464a035ec 2010-11-20 kinaba: class RuntimeException : Exception { mixin ExceptionWithPosition; } /// Evaluator errors 2134cd44cc 2010-11-23 kinaba: 2134cd44cc 2010-11-23 kinaba: /// Per-thread call stack management. 2134cd44cc 2010-11-23 kinaba: /// This scoped class's ctor&dtor maintain the callstack. 2134cd44cc 2010-11-23 kinaba: /// TODO: make it "per-evaluator" !!!!!!!!!!! 2134cd44cc 2010-11-23 kinaba: 2134cd44cc 2010-11-23 kinaba: scope class PushCallStack 2134cd44cc 2010-11-23 kinaba: { 2134cd44cc 2010-11-23 kinaba: this(LexPosition pos, string msg) { callstackEnterFunction(pos,msg); } 2134cd44cc 2010-11-23 kinaba: ~this() { callstackLeaveFunction(); } 2134cd44cc 2010-11-23 kinaba: } 2134cd44cc 2010-11-23 kinaba: 2134cd44cc 2010-11-23 kinaba: LexPosition[] callstack_pos; 2134cd44cc 2010-11-23 kinaba: string[] callstack_msg; 2134cd44cc 2010-11-23 kinaba: 2134cd44cc 2010-11-23 kinaba: private void callstackEnterFunction(LexPosition pos, string msg) 2134cd44cc 2010-11-23 kinaba: { 2134cd44cc 2010-11-23 kinaba: callstack_pos ~= pos; 2134cd44cc 2010-11-23 kinaba: callstack_msg ~= msg; 2134cd44cc 2010-11-23 kinaba: } 2134cd44cc 2010-11-23 kinaba: 2134cd44cc 2010-11-23 kinaba: private void callstackLeaveFunction() 2134cd44cc 2010-11-23 kinaba: { 2134cd44cc 2010-11-23 kinaba: callstack_pos.length -= 1; 2134cd44cc 2010-11-23 kinaba: callstack_msg.length -= 1; 2134cd44cc 2010-11-23 kinaba: }