root/trunk/orca/error.c

Revision 154, 4.7 kB (checked in by krobillard, 2 years ago)

Orca - Replaced atom variables with fixed atom defines.

Line 
1/*============================================================================
2    ORCA Interpreter
3    Copyright (C) 2005-2006  Karl Robillard
4
5    This library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    This library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with this library; if not, write to the Free Software
17    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18===========================================================================*/
19
20
21#include "os.h"
22#include "ovalue.h"
23#include "internal.h"
24#include "orca_atoms.h"
25
26
27/**
28  orLookupPath is provided as a fast but still convenient method of resolving
29  paths from C code.
30
31  Pass a sequence of datatype (OT_*) / value (atom/index) pairs terminated
32  by OR_LPATH_END to specify the path.
33
34  Returns zero if the path is not valid.
35
36  Using a string argument rather than a tag list would be more convenient
37  but not as quick.
38*/
39OValue* orLookupPath( int first_tag, ... )
40{
41    va_list args;
42    int tag;
43    int data;
44    OIndex wrd;
45    OContext ctx;
46    OValue* val;
47    OBlock* blk;
48
49    orGlobalCtx( ctx );
50    blk = 0;
51    val = 0;
52
53    va_start(args, first_tag);
54    tag = first_tag;
55
56    while( tag != OR_LPATH_END )
57    {
58        data = va_arg(args, int);
59        switch( tag )
60        {
61            case OT_WORD:
62                wrd = orLookup( &ctx, data );
63                if( wrd < 0 )
64                {
65                    val = 0;
66                    goto abort;
67                }
68                {
69                OBlock* vblk = orBlockPtr( ctx.vblkN );
70                val = vblk->values + wrd;
71                if( orIs(val, OT_OBJECT) )
72                {
73                    ctx = val->ctx;
74                    blk = 0;
75                }
76                else if( orIs(val, OT_BLOCK) )
77                {
78                    orGlobalCtx( ctx );
79                    blk = orBLOCKS + val->index;
80                }
81                }
82                break;
83
84            case OT_INTEGER:
85                if( ! blk )
86                {
87                    val = 0;
88                    goto abort;
89                }
90                val = blk->values + data;
91                break;
92
93            default:
94                val = 0;
95                goto abort;
96                break;
97        }
98        tag = va_arg(args, int);
99    }
100
101abort:
102
103    va_end(args);
104
105    return val;
106}
107
108
109/**
110  Convert error! to object!.
111*/
112OR_NATIVE_PUB( orDisarmNative )
113{
114    if( orIs(a1, OT_ERROR) )
115    {
116        OValue* val;
117        OValue* tval;
118
119        val = orLookupPath( OT_WORD, OR_ATOM_SYSTEM,
120                            OT_WORD, OR_ATOM_ERROR,
121                            OR_LPATH_END );
122        if( val && orIs(val, OT_OBJECT) )
123        {
124            int errType;
125            OContext ctx;
126            OBlock* vblk;
127
128            // self msg: type: id: near: none
129
130            orCloneObject( &val->ctx, &ctx );
131            vblk = orBlockPtr( ctx.vblkN );
132
133            val = vblk->values + 1;
134
135            errType = orErrorType(a1);
136
137            if( errType == OR_ERROR_THROW )
138            {
139                OContext gctx;
140                orGlobalCtx( gctx );
141
142                orSetTF( val, OT_WORD );
143                orSetWord( val, GLOBAL_WORDS_BLKN, GLOBAL_CTXN,
144                           orLookup( &gctx, a1->error.msg ),
145                           a1->error.msg );
146            }
147            else
148            {
149                orSetTF( val, OT_STRING );
150                orSetSeries( val, a1->error.msg, 0 );
151            }
152
153
154            tval = orLookupPath( OT_WORD, OR_ATOM_SYSTEM,
155                                 OT_WORD, OR_ATOM_ERROR_TYPES,
156                                 OR_LPATH_END );
157            ++val;
158            if( tval && orIs(tval, OT_BLOCK) )
159            {
160                OBlock* blk = orBLOCK(tval);
161                if( errType < blk->used )
162                {
163                    *val = blk->values[ errType ];
164                    goto end_type;
165                }
166            }
167            orSetTF( val, OT_INTEGER );
168            orInt(val) = errType;
169end_type:
170
171            /* id
172            ++val;
173            orSetTF( val, OT_INTEGER );
174            orInt(val) = a1->error.msg;
175            */
176
177            orSetTF( a1, OT_OBJECT );
178            a1->ctx = ctx;
179            return;
180        }
181    }
182    orResultNONE
183}
184
185
186/*EOF*/
Note: See TracBrowser for help on using the browser.