changed to handle the error literal in the compiler.

added stix_synerrnumtoerrstr().
This commit is contained in:
hyunghwan.chung 2016-12-28 19:12:14 +00:00
parent eea13c0bd2
commit 2bf8b591cf
9 changed files with 453 additions and 225 deletions

View File

@ -245,6 +245,16 @@
## { ## {
## ^0 ## ^0
## } ## }
#method asError
{
<primitive: #_smooi_as_error>
}
#method asCharacter
{
<primitive: #_smooi_as_character>
}
} }
#class(#liword) LargeInteger(Integer) #class(#liword) LargeInteger(Integer)

View File

@ -4,9 +4,9 @@
{ {
#method(#class) main #method(#class) main
{ {
| s c f | | errmsgs synerrmsgs f |
s := #( errmsgs := #(
'no error' 'no error'
'generic error' 'generic error'
@ -41,34 +41,106 @@
'encoding conversion error' 'encoding conversion error'
). ).
synerrmsgs := #(
'no error'
'illegal character'
'comment not closed'
'string not closed'
'no character after $'
'no valid character after #'
'wrong character literal'
'colon expected'
'string expected'
'invalid radix'
'invalid numeric literal'
'byte too small or too large'
'wrong error literal'
'{ expected'
'} expected'
'( expected'
') expected'
'] expected'
'. expected'
' expected'
'| expected'
'> expected'
':= expected'
'identifier expected'
'integer expected'
'primitive: expected'
'wrong directive'
'undefined class'
'duplicate class'
'contradictory class definition'
'#dcl not allowed'
'wrong method name'
'duplicate method name'
'duplicate argument name'
'duplicate temporary variable name'
'duplicate variable name'
'duplicate block argument name'
'cannot assign to argument'
'undeclared variable'
'unusable variable in compiled code'
'inaccessible variable'
'ambiguous variable'
'wrong expression primary'
'too many temporaries'
'too many arguments'
'too many block temporaries'
'too many block arguments'
'too large block'
'wrong primitive function number'
'wrong primitive function identifier'
'wrong module name'
'#include error'
'wrong namespace name'
'wrong pool dictionary name'
'duplicate pool dictionary name'
'literal expected'
).
f := Stdio open: 'generr.out' for: 'w'. f := Stdio open: 'generr.out' for: 'w'.
[ f isError ] ifTrue: [ System logNl: 'Cannot open generr.out'. thisProcess terminate. ]. [ f isError ] ifTrue: [ System logNl: 'Cannot open generr.out'. thisProcess terminate. ].
c := s size - 1. self emitMessages: errmsgs named: 'errstr' on: f.
self emitMessages: synerrmsgs named: 'synerrstr' on: f.
f close.
}
#method(#class) emitMessages: errmsgs named: name on: f
{
| c prefix |
prefix := name & '_'.
c := errmsgs size - 1.
0 to: c do: [:i | 0 to: c do: [:i |
self printString: (s at: i) index: i on: f. self printString: (errmsgs at: i) prefix: prefix index: i on: f.
]. ].
f puts: S'static stix_ooch_t* errstr[] =\n{\n'.
f puts: S'static stix_ooch_t* '.
f puts: name.
f puts: S'[] =\n{\n'.
0 to: c do: [:i | 0 to: c do: [:i |
((i rem: 8) = 0) ifTrue: [ f putc: C'\t' ]. ((i rem: 8) = 0) ifTrue: [ f putc: C'\t' ].
f puts: S'e'. f puts: prefix.
f puts: (i asString). f puts: (i asString).
(i = c) ifFalse: [f puts: S',' ]. (i = c) ifFalse: [f puts: S',' ].
(((i + 1) rem: 8) = 0) ifTrue: [ f putc: C'\n' ] ifFalse: [ f putc: C' ' ]. (((i + 1) rem: 8) = 0) ifTrue: [ f putc: C'\n' ] ifFalse: [ f putc: C' ' ].
]. ].
(((c + 1) rem: 8) = 0) ifFalse: [ f putc: C'\n' ]. (((c + 1) rem: 8) = 0) ifFalse: [ f putc: C'\n' ].
f puts: S'};\n'. f puts: S'};\n'.
f close.
} }
#method(#class) printString: s index: index on: f #method(#class) printString: s prefix: prefix index: index on: f
{ {
| c | | c |
c := s size - 1. c := s size - 1.
f puts: 'static stix_ooch_t e'. f puts: 'static stix_ooch_t '.
f puts: prefix.
f puts: index asString. f puts: index asString.
f puts: '[] = {'. f puts: '[] = {'.

View File

@ -184,6 +184,12 @@
2r100000000_10001111_01010000 dump. 2r100000000_10001111_01010000 dump.
16rFFFFFFFF_12345678 dump. 16rFFFFFFFF_12345678 dump.
(v1 := self t001()) isError ifTrue: [('t001 Error 111....' & v1 asInteger asString) dump].
(v1 := self t001(10)) isError ifTrue: [('t001 Error 222....' & v1 asInteger asString) dump].
(v1 := self t001(20)) isError ifTrue: [('t001 Error 333....' & v1 asInteger asString) dump].
error(9999) dump.
error(9999) asInteger dump.
} }
#method(#class) varg_test() #method(#class) varg_test()
@ -209,15 +215,18 @@
^f ^f
} }
#method t001(a) #method(#class) t001(a)
{ {
a isNil ifTrue: [^E'1']. a isNil ifTrue: [^error(10)].
(a = 20) ifTrue: [^error]. (a = 20) ifTrue: [^error].
(a = 10) ifTrue: [^10]. (a = 10) ifTrue: [^123 asError].
^a. ^a.
a := error(10). #! a := error(10).
[ a = error(10) ] ifTrue: [....]. #! [ a = error(10) ] ifTrue: [....].
#! self t001 (error:10).
#! self t001: (error:10)
} }
} }

View File

@ -505,6 +505,26 @@ static stix_oop_t string_to_num (stix_t* stix, stix_oocs_t* str, int radixed)
return stix_strtoint (stix, ptr, end - ptr, base); return stix_strtoint (stix, ptr, end - ptr, base);
} }
static stix_oop_t string_to_error (stix_t* stix, stix_oocs_t* str)
{
stix_ooi_t num = 0;
const stix_ooch_t* ptr, * end;
ptr = str->ptr,
end = str->ptr + str->len;
/* i assume that the input is in the form of error(NNN)
* all other letters are non-digits except the NNN part.
* i just skip all non-digit letters for simplicity sake. */
while (ptr < end)
{
if (is_digitchar(*ptr)) num = num * 10 + (*ptr - '0');
ptr++;
}
return STIX_ERROR_TO_OOP(num);
}
/* --------------------------------------------------------------------- /* ---------------------------------------------------------------------
* Tokenizer * Tokenizer
* --------------------------------------------------------------------- */ * --------------------------------------------------------------------- */
@ -802,7 +822,37 @@ static int get_ident (stix_t* stix, stix_ooci_t char_read_ahead)
} }
while (is_identchar(c)); while (is_identchar(c));
if (c == ':') if (c == '(' && is_token_word(stix, VOCA_ERROR))
{
/* error(NN) */
ADD_TOKEN_CHAR (stix, c);
GET_CHAR_TO (stix, c);
if (!is_digitchar(c))
{
ADD_TOKEN_CHAR (stix, c);
set_syntax_error (stix, STIX_SYNERR_ERRLIT, TOKEN_LOC(stix), TOKEN_NAME(stix));
return -1;
}
do
{
ADD_TOKEN_CHAR (stix, c);
GET_CHAR_TO (stix, c);
}
while (is_digitchar(c));
if (c != ')')
{
set_syntax_error (stix, STIX_SYNERR_RPAREN, LEXER_LOC(stix), STIX_NULL);
return -1;
}
/* TODO: error number range check */
ADD_TOKEN_CHAR (stix, c);
SET_TOKEN_TYPE (stix, STIX_IOTOK_ERRLIT);
}
else if (c == ':')
{ {
read_more_kwsym: read_more_kwsym:
ADD_TOKEN_CHAR (stix, c); ADD_TOKEN_CHAR (stix, c);
@ -895,7 +945,7 @@ static int get_ident (stix_t* stix, stix_ooci_t char_read_ahead)
} }
else if (is_token_word(stix, VOCA_ERROR)) else if (is_token_word(stix, VOCA_ERROR))
{ {
SET_TOKEN_TYPE (stix, STIX_IOTOK_ERRLIT); SET_TOKEN_TYPE (stix, STIX_IOTOK_ERROR);
} }
else if (is_token_word(stix, VOCA_THIS_CONTEXT)) else if (is_token_word(stix, VOCA_THIS_CONTEXT))
{ {
@ -3522,9 +3572,12 @@ static int __read_array_literal (stix_t* stix, stix_oop_t* xlit)
lit = stix->_false; lit = stix->_false;
break; break;
case STIX_IOTOK_ERROR:
lit = STIX_ERROR_TO_OOP(STIX_EGENERIC);
break;
case STIX_IOTOK_ERRLIT: case STIX_IOTOK_ERRLIT:
/* AAAAAAAAA */ lit = string_to_error (stix, TOKEN_NAME(stix));
lit = string_to_num (stix, TOKEN_NAME(stix), TOKEN_TYPE(stix) == STIX_IOTOK_RADNUMLIT);
break; break;
case STIX_IOTOK_ARPAREN: /* #( */ case STIX_IOTOK_ARPAREN: /* #( */
@ -3742,10 +3795,26 @@ static int compile_expression_primary (stix_t* stix, const stix_oocs_t* ident, c
GET_TOKEN (stix); GET_TOKEN (stix);
break; break;
case STIX_IOTOK_ERRLIT: case STIX_IOTOK_ERROR:
/* AAAAAA */ if (add_literal(stix, STIX_ERROR_TO_OOP(STIX_EGENERIC), &index) <= -1 ||
emit_single_param_instruction(stix, BCODE_PUSH_LITERAL_0, index) <= -1) return -1;
GET_TOKEN (stix);
break; break;
case STIX_IOTOK_ERRLIT:
{
stix_oop_t tmp;
tmp = string_to_error (stix, TOKEN_NAME(stix));
if (!tmp) return -1;
if (add_literal(stix, tmp, &index) <= -1 ||
emit_single_param_instruction(stix, BCODE_PUSH_LITERAL_0, index) <= -1) return -1;
GET_TOKEN (stix);
break;
}
case STIX_IOTOK_THIS_CONTEXT: case STIX_IOTOK_THIS_CONTEXT:
if (emit_byte_instruction(stix, BCODE_PUSH_CONTEXT) <= -1) return -1; if (emit_byte_instruction(stix, BCODE_PUSH_CONTEXT) <= -1) return -1;
GET_TOKEN (stix); GET_TOKEN (stix);
@ -5287,8 +5356,12 @@ static int __compile_pooldic_definition (stix_t* stix)
lit = stix->_false; lit = stix->_false;
goto add_literal; goto add_literal;
case STIX_IOTOK_ERROR:
lit = STIX_ERROR_TO_OOP(STIX_EGENERIC);
goto add_literal;
case STIX_IOTOK_ERRLIT: case STIX_IOTOK_ERRLIT:
/* AAAAAAAAAAAA */ lit = string_to_error (stix, TOKEN_NAME(stix));
goto add_literal; goto add_literal;
case STIX_IOTOK_CHARLIT: case STIX_IOTOK_CHARLIT:

View File

@ -30,42 +30,110 @@
/* BEGIN: GENERATED WITH generr.st */ /* BEGIN: GENERATED WITH generr.st */
static stix_ooch_t e0[] = {'n','o',' ','e','r','r','o','r','\0'}; static stix_ooch_t errstr_0[] = {'n','o',' ','e','r','r','o','r','\0'};
static stix_ooch_t e1[] = {'g','e','n','e','r','i','c',' ','e','r','r','o','r','\0'}; static stix_ooch_t errstr_1[] = {'g','e','n','e','r','i','c',' ','e','r','r','o','r','\0'};
static stix_ooch_t e2[] = {'n','o','t',' ','i','m','p','l','e','m','e','n','t','e','d','\0'}; static stix_ooch_t errstr_2[] = {'n','o','t',' ','i','m','p','l','e','m','e','n','t','e','d','\0'};
static stix_ooch_t e3[] = {'s','u','b','s','y','s','t','e','m',' ','e','r','r','o','r','\0'}; static stix_ooch_t errstr_3[] = {'s','u','b','s','y','s','t','e','m',' ','e','r','r','o','r','\0'};
static stix_ooch_t e4[] = {'i','n','t','e','r','n','a','l',' ','e','r','r','o','r',' ','t','h','a','t',' ','s','h','o','u','l','d',' ','n','e','v','e','r',' ','h','a','v','e',' ','h','a','p','p','e','n','e','d','\0'}; static stix_ooch_t errstr_4[] = {'i','n','t','e','r','n','a','l',' ','e','r','r','o','r',' ','t','h','a','t',' ','s','h','o','u','l','d',' ','n','e','v','e','r',' ','h','a','v','e',' ','h','a','p','p','e','n','e','d','\0'};
static stix_ooch_t e5[] = {'i','n','s','u','f','f','i','c','i','e','n','t',' ','s','y','s','t','e','m',' ','m','e','m','o','r','y','\0'}; static stix_ooch_t errstr_5[] = {'i','n','s','u','f','f','i','c','i','e','n','t',' ','s','y','s','t','e','m',' ','m','e','m','o','r','y','\0'};
static stix_ooch_t e6[] = {'i','n','s','u','f','f','i','c','i','e','n','t',' ','o','b','j','e','c','t',' ','m','e','m','o','r','y','\0'}; static stix_ooch_t errstr_6[] = {'i','n','s','u','f','f','i','c','i','e','n','t',' ','o','b','j','e','c','t',' ','m','e','m','o','r','y','\0'};
static stix_ooch_t e7[] = {'i','n','v','a','l','i','d',' ','p','a','r','a','m','e','t','e','r',' ','o','r',' ','a','r','g','u','m','e','n','t','\0'}; static stix_ooch_t errstr_7[] = {'i','n','v','a','l','i','d',' ','p','a','r','a','m','e','t','e','r',' ','o','r',' ','a','r','g','u','m','e','n','t','\0'};
static stix_ooch_t e8[] = {'d','a','t','a',' ','n','o','t',' ','f','o','u','n','d','\0'}; static stix_ooch_t errstr_8[] = {'d','a','t','a',' ','n','o','t',' ','f','o','u','n','d','\0'};
static stix_ooch_t e9[] = {'e','x','i','s','t','i','n','g','/','d','u','p','l','i','c','a','t','e',' ','d','a','t','a','\0'}; static stix_ooch_t errstr_9[] = {'e','x','i','s','t','i','n','g','/','d','u','p','l','i','c','a','t','e',' ','d','a','t','a','\0'};
static stix_ooch_t e10[] = {'b','u','s','y','\0'}; static stix_ooch_t errstr_10[] = {'b','u','s','y','\0'};
static stix_ooch_t e11[] = {'a','c','c','e','s','s',' ','d','e','n','i','e','d','\0'}; static stix_ooch_t errstr_11[] = {'a','c','c','e','s','s',' ','d','e','n','i','e','d','\0'};
static stix_ooch_t e12[] = {'o','p','e','r','a','t','i','o','n',' ','n','o','t',' ','p','e','r','m','i','t','t','e','d','\0'}; static stix_ooch_t errstr_12[] = {'o','p','e','r','a','t','i','o','n',' ','n','o','t',' ','p','e','r','m','i','t','t','e','d','\0'};
static stix_ooch_t e13[] = {'n','o','t',' ','a',' ','d','i','r','e','c','t','o','r','y','\0'}; static stix_ooch_t errstr_13[] = {'n','o','t',' ','a',' ','d','i','r','e','c','t','o','r','y','\0'};
static stix_ooch_t e14[] = {'i','n','t','e','r','r','u','p','t','e','d','\0'}; static stix_ooch_t errstr_14[] = {'i','n','t','e','r','r','u','p','t','e','d','\0'};
static stix_ooch_t e15[] = {'p','i','p','e',' ','e','r','r','o','r','\0'}; static stix_ooch_t errstr_15[] = {'p','i','p','e',' ','e','r','r','o','r','\0'};
static stix_ooch_t e16[] = {'r','e','s','o','u','r','c','e',' ','t','e','m','p','o','r','a','r','i','l','y',' ','u','n','a','v','a','i','l','a','b','l','e','\0'}; static stix_ooch_t errstr_16[] = {'r','e','s','o','u','r','c','e',' ','t','e','m','p','o','r','a','r','i','l','y',' ','u','n','a','v','a','i','l','a','b','l','e','\0'};
static stix_ooch_t e17[] = {'d','a','t','a',' ','t','o','o',' ','l','a','r','g','e','\0'}; static stix_ooch_t errstr_17[] = {'d','a','t','a',' ','t','o','o',' ','l','a','r','g','e','\0'};
static stix_ooch_t e18[] = {'m','e','s','s','a','g','e',' ','s','e','n','d','i','n','g',' ','e','r','r','o','r','\0'}; static stix_ooch_t errstr_18[] = {'m','e','s','s','a','g','e',' ','s','e','n','d','i','n','g',' ','e','r','r','o','r','\0'};
static stix_ooch_t e19[] = {'r','a','n','g','e',' ','e','r','r','o','r','\0'}; static stix_ooch_t errstr_19[] = {'r','a','n','g','e',' ','e','r','r','o','r','\0'};
static stix_ooch_t e20[] = {'b','y','t','e','-','c','o','d','e',' ','f','u','l','l','\0'}; static stix_ooch_t errstr_20[] = {'b','y','t','e','-','c','o','d','e',' ','f','u','l','l','\0'};
static stix_ooch_t e21[] = {'d','i','c','t','i','o','n','a','r','y',' ','f','u','l','l','\0'}; static stix_ooch_t errstr_21[] = {'d','i','c','t','i','o','n','a','r','y',' ','f','u','l','l','\0'};
static stix_ooch_t e22[] = {'p','r','o','c','e','s','s','o','r',' ','f','u','l','l','\0'}; static stix_ooch_t errstr_22[] = {'p','r','o','c','e','s','s','o','r',' ','f','u','l','l','\0'};
static stix_ooch_t e23[] = {'s','e','m','a','p','h','o','r','e',' ','h','e','a','p',' ','f','u','l','l','\0'}; static stix_ooch_t errstr_23[] = {'s','e','m','a','p','h','o','r','e',' ','h','e','a','p',' ','f','u','l','l','\0'};
static stix_ooch_t e24[] = {'s','e','m','a','p','h','o','r','e',' ','l','i','s','t',' ','f','u','l','l','\0'}; static stix_ooch_t errstr_24[] = {'s','e','m','a','p','h','o','r','e',' ','l','i','s','t',' ','f','u','l','l','\0'};
static stix_ooch_t e25[] = {'d','i','v','i','d','e',' ','b','y',' ','z','e','r','o','\0'}; static stix_ooch_t errstr_25[] = {'d','i','v','i','d','e',' ','b','y',' ','z','e','r','o','\0'};
static stix_ooch_t e26[] = {'I','/','O',' ','e','r','r','o','r','\0'}; static stix_ooch_t errstr_26[] = {'I','/','O',' ','e','r','r','o','r','\0'};
static stix_ooch_t e27[] = {'e','n','c','o','d','i','n','g',' ','c','o','n','v','e','r','s','i','o','n',' ','e','r','r','o','r','\0'}; static stix_ooch_t errstr_27[] = {'e','n','c','o','d','i','n','g',' ','c','o','n','v','e','r','s','i','o','n',' ','e','r','r','o','r','\0'};
static stix_ooch_t* errstr[] = static stix_ooch_t* errstr[] =
{ {
e0, e1, e2, e3, e4, e5, e6, e7, errstr_0, errstr_1, errstr_2, errstr_3, errstr_4, errstr_5, errstr_6, errstr_7,
e8, e9, e10, e11, e12, e13, e14, e15, errstr_8, errstr_9, errstr_10, errstr_11, errstr_12, errstr_13, errstr_14, errstr_15,
e16, e17, e18, e19, e20, e21, e22, e23, errstr_16, errstr_17, errstr_18, errstr_19, errstr_20, errstr_21, errstr_22, errstr_23,
e24, e25, e26, e27 errstr_24, errstr_25, errstr_26, errstr_27
}; };
#if defined(STIX_INCLUDE_COMPILER)
static stix_ooch_t synerrstr_0[] = {'n','o',' ','e','r','r','o','r','\0'};
static stix_ooch_t synerrstr_1[] = {'i','l','l','e','g','a','l',' ','c','h','a','r','a','c','t','e','r','\0'};
static stix_ooch_t synerrstr_2[] = {'c','o','m','m','e','n','t',' ','n','o','t',' ','c','l','o','s','e','d','\0'};
static stix_ooch_t synerrstr_3[] = {'s','t','r','i','n','g',' ','n','o','t',' ','c','l','o','s','e','d','\0'};
static stix_ooch_t synerrstr_4[] = {'n','o',' ','c','h','a','r','a','c','t','e','r',' ','a','f','t','e','r',' ','$','\0'};
static stix_ooch_t synerrstr_5[] = {'n','o',' ','v','a','l','i','d',' ','c','h','a','r','a','c','t','e','r',' ','a','f','t','e','r',' ','#','\0'};
static stix_ooch_t synerrstr_6[] = {'w','r','o','n','g',' ','c','h','a','r','a','c','t','e','r',' ','l','i','t','e','r','a','l','\0'};
static stix_ooch_t synerrstr_7[] = {'c','o','l','o','n',' ','e','x','p','e','c','t','e','d','\0'};
static stix_ooch_t synerrstr_8[] = {'s','t','r','i','n','g',' ','e','x','p','e','c','t','e','d','\0'};
static stix_ooch_t synerrstr_9[] = {'i','n','v','a','l','i','d',' ','r','a','d','i','x','\0'};
static stix_ooch_t synerrstr_10[] = {'i','n','v','a','l','i','d',' ','n','u','m','e','r','i','c',' ','l','i','t','e','r','a','l','\0'};
static stix_ooch_t synerrstr_11[] = {'b','y','t','e',' ','t','o','o',' ','s','m','a','l','l',' ','o','r',' ','t','o','o',' ','l','a','r','g','e','\0'};
static stix_ooch_t synerrstr_12[] = {'w','r','o','n','g',' ','e','r','r','o','r',' ','l','i','t','e','r','a','l','\0'};
static stix_ooch_t synerrstr_13[] = {'{',' ','e','x','p','e','c','t','e','d','\0'};
static stix_ooch_t synerrstr_14[] = {'}',' ','e','x','p','e','c','t','e','d','\0'};
static stix_ooch_t synerrstr_15[] = {'(',' ','e','x','p','e','c','t','e','d','\0'};
static stix_ooch_t synerrstr_16[] = {')',' ','e','x','p','e','c','t','e','d','\0'};
static stix_ooch_t synerrstr_17[] = {']',' ','e','x','p','e','c','t','e','d','\0'};
static stix_ooch_t synerrstr_18[] = {'.',' ','e','x','p','e','c','t','e','d','\0'};
static stix_ooch_t synerrstr_19[] = {' ','e','x','p','e','c','t','e','d','\0'};
static stix_ooch_t synerrstr_20[] = {'|',' ','e','x','p','e','c','t','e','d','\0'};
static stix_ooch_t synerrstr_21[] = {'>',' ','e','x','p','e','c','t','e','d','\0'};
static stix_ooch_t synerrstr_22[] = {':','=',' ','e','x','p','e','c','t','e','d','\0'};
static stix_ooch_t synerrstr_23[] = {'i','d','e','n','t','i','f','i','e','r',' ','e','x','p','e','c','t','e','d','\0'};
static stix_ooch_t synerrstr_24[] = {'i','n','t','e','g','e','r',' ','e','x','p','e','c','t','e','d','\0'};
static stix_ooch_t synerrstr_25[] = {'p','r','i','m','i','t','i','v','e',':',' ','e','x','p','e','c','t','e','d','\0'};
static stix_ooch_t synerrstr_26[] = {'w','r','o','n','g',' ','d','i','r','e','c','t','i','v','e','\0'};
static stix_ooch_t synerrstr_27[] = {'u','n','d','e','f','i','n','e','d',' ','c','l','a','s','s','\0'};
static stix_ooch_t synerrstr_28[] = {'d','u','p','l','i','c','a','t','e',' ','c','l','a','s','s','\0'};
static stix_ooch_t synerrstr_29[] = {'c','o','n','t','r','a','d','i','c','t','o','r','y',' ','c','l','a','s','s',' ','d','e','f','i','n','i','t','i','o','n','\0'};
static stix_ooch_t synerrstr_30[] = {'#','d','c','l',' ','n','o','t',' ','a','l','l','o','w','e','d','\0'};
static stix_ooch_t synerrstr_31[] = {'w','r','o','n','g',' ','m','e','t','h','o','d',' ','n','a','m','e','\0'};
static stix_ooch_t synerrstr_32[] = {'d','u','p','l','i','c','a','t','e',' ','m','e','t','h','o','d',' ','n','a','m','e','\0'};
static stix_ooch_t synerrstr_33[] = {'d','u','p','l','i','c','a','t','e',' ','a','r','g','u','m','e','n','t',' ','n','a','m','e','\0'};
static stix_ooch_t synerrstr_34[] = {'d','u','p','l','i','c','a','t','e',' ','t','e','m','p','o','r','a','r','y',' ','v','a','r','i','a','b','l','e',' ','n','a','m','e','\0'};
static stix_ooch_t synerrstr_35[] = {'d','u','p','l','i','c','a','t','e',' ','v','a','r','i','a','b','l','e',' ','n','a','m','e','\0'};
static stix_ooch_t synerrstr_36[] = {'d','u','p','l','i','c','a','t','e',' ','b','l','o','c','k',' ','a','r','g','u','m','e','n','t',' ','n','a','m','e','\0'};
static stix_ooch_t synerrstr_37[] = {'c','a','n','n','o','t',' ','a','s','s','i','g','n',' ','t','o',' ','a','r','g','u','m','e','n','t','\0'};
static stix_ooch_t synerrstr_38[] = {'u','n','d','e','c','l','a','r','e','d',' ','v','a','r','i','a','b','l','e','\0'};
static stix_ooch_t synerrstr_39[] = {'u','n','u','s','a','b','l','e',' ','v','a','r','i','a','b','l','e',' ','i','n',' ','c','o','m','p','i','l','e','d',' ','c','o','d','e','\0'};
static stix_ooch_t synerrstr_40[] = {'i','n','a','c','c','e','s','s','i','b','l','e',' ','v','a','r','i','a','b','l','e','\0'};
static stix_ooch_t synerrstr_41[] = {'a','m','b','i','g','u','o','u','s',' ','v','a','r','i','a','b','l','e','\0'};
static stix_ooch_t synerrstr_42[] = {'w','r','o','n','g',' ','e','x','p','r','e','s','s','i','o','n',' ','p','r','i','m','a','r','y','\0'};
static stix_ooch_t synerrstr_43[] = {'t','o','o',' ','m','a','n','y',' ','t','e','m','p','o','r','a','r','i','e','s','\0'};
static stix_ooch_t synerrstr_44[] = {'t','o','o',' ','m','a','n','y',' ','a','r','g','u','m','e','n','t','s','\0'};
static stix_ooch_t synerrstr_45[] = {'t','o','o',' ','m','a','n','y',' ','b','l','o','c','k',' ','t','e','m','p','o','r','a','r','i','e','s','\0'};
static stix_ooch_t synerrstr_46[] = {'t','o','o',' ','m','a','n','y',' ','b','l','o','c','k',' ','a','r','g','u','m','e','n','t','s','\0'};
static stix_ooch_t synerrstr_47[] = {'t','o','o',' ','l','a','r','g','e',' ','b','l','o','c','k','\0'};
static stix_ooch_t synerrstr_48[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','n','u','m','b','e','r','\0'};
static stix_ooch_t synerrstr_49[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','i','d','e','n','t','i','f','i','e','r','\0'};
static stix_ooch_t synerrstr_50[] = {'w','r','o','n','g',' ','m','o','d','u','l','e',' ','n','a','m','e','\0'};
static stix_ooch_t synerrstr_51[] = {'#','i','n','c','l','u','d','e',' ','e','r','r','o','r','\0'};
static stix_ooch_t synerrstr_52[] = {'w','r','o','n','g',' ','n','a','m','e','s','p','a','c','e',' ','n','a','m','e','\0'};
static stix_ooch_t synerrstr_53[] = {'w','r','o','n','g',' ','p','o','o','l',' ','d','i','c','t','i','o','n','a','r','y',' ','n','a','m','e','\0'};
static stix_ooch_t synerrstr_54[] = {'d','u','p','l','i','c','a','t','e',' ','p','o','o','l',' ','d','i','c','t','i','o','n','a','r','y',' ','n','a','m','e','\0'};
static stix_ooch_t synerrstr_55[] = {'l','i','t','e','r','a','l',' ','e','x','p','e','c','t','e','d','\0'};
static stix_ooch_t* synerrstr[] =
{
synerrstr_0, synerrstr_1, synerrstr_2, synerrstr_3, synerrstr_4, synerrstr_5, synerrstr_6, synerrstr_7,
synerrstr_8, synerrstr_9, synerrstr_10, synerrstr_11, synerrstr_12, synerrstr_13, synerrstr_14, synerrstr_15,
synerrstr_16, synerrstr_17, synerrstr_18, synerrstr_19, synerrstr_20, synerrstr_21, synerrstr_22, synerrstr_23,
synerrstr_24, synerrstr_25, synerrstr_26, synerrstr_27, synerrstr_28, synerrstr_29, synerrstr_30, synerrstr_31,
synerrstr_32, synerrstr_33, synerrstr_34, synerrstr_35, synerrstr_36, synerrstr_37, synerrstr_38, synerrstr_39,
synerrstr_40, synerrstr_41, synerrstr_42, synerrstr_43, synerrstr_44, synerrstr_45, synerrstr_46, synerrstr_47,
synerrstr_48, synerrstr_49, synerrstr_50, synerrstr_51, synerrstr_52, synerrstr_53, synerrstr_54, synerrstr_55
};
#endif
/* END: GENERATED WITH generr.st */ /* END: GENERATED WITH generr.st */
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
@ -77,6 +145,14 @@ const stix_ooch_t* stix_errnumtoerrstr (stix_errnum_t errnum)
return (errnum >= 0 && errnum < STIX_COUNTOF(errstr))? errstr[errnum]: e_unknown; return (errnum >= 0 && errnum < STIX_COUNTOF(errstr))? errstr[errnum]: e_unknown;
} }
#if defined(STIX_INCLUDE_COMPILER)
const stix_ooch_t* stix_synerrnumtoerrstr (stix_synerrnum_t errnum)
{
static stix_ooch_t e_unknown[] = {'u','n','k','n','o','w','n',' ','e','r','r','o','r','\0'};
return (errnum >= 0 && errnum < STIX_COUNTOF(synerrstr))? synerrstr[errnum]: e_unknown;
}
#endif
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
* SYSTEM DEPENDENT FUNCTIONS * SYSTEM DEPENDENT FUNCTIONS
* -------------------------------------------------------------------------- */ * -------------------------------------------------------------------------- */

View File

@ -2409,6 +2409,38 @@ static int pf_integer_inttostr (stix_t* stix, stix_ooi_t nargs)
return 1; return 1;
} }
static int pf_smooi_as_character (stix_t* stix, stix_ooi_t nargs)
{
stix_oop_t rcv;
stix_ooi_t ec;
STIX_ASSERT (stix, nargs == 0);
rcv = STIX_STACK_GETRCV(stix, nargs);
if (!STIX_OOP_IS_SMOOI(rcv)) return 0;
ec = STIX_OOP_TO_SMOOI(rcv);
if (ec < 0) ec = 0;
STIX_STACK_SETRET (stix, nargs, STIX_CHAR_TO_OOP(ec));
return 1;
}
static int pf_smooi_as_error (stix_t* stix, stix_ooi_t nargs)
{
stix_oop_t rcv;
stix_ooi_t ec;
STIX_ASSERT (stix, nargs == 0);
rcv = STIX_STACK_GETRCV(stix, nargs);
if (!STIX_OOP_IS_SMOOI(rcv)) return 0;
ec = STIX_OOP_TO_SMOOI(rcv);
if (ec < 0) ec = 0;
STIX_STACK_SETRET (stix, nargs, STIX_ERROR_TO_OOP(ec));
return 1;
}
static int pf_error_as_character (stix_t* stix, stix_ooi_t nargs) static int pf_error_as_character (stix_t* stix, stix_ooi_t nargs)
{ {
stix_oop_t rcv; stix_oop_t rcv;
@ -2816,6 +2848,9 @@ static pf_t pftab[] =
{ 1, 1, pf_integer_ge, "_integer_ge" }, { 1, 1, pf_integer_ge, "_integer_ge" },
{ 1, 1, pf_integer_inttostr, "_integer_inttostr" }, { 1, 1, pf_integer_inttostr, "_integer_inttostr" },
{ 0, 0, pf_smooi_as_character, "_smooi_as_character" },
{ 0, 0, pf_smooi_as_error, "_smooi_as_error" },
{ 0, 0, pf_error_as_character, "_error_as_character" }, { 0, 0, pf_error_as_character, "_error_as_character" },
{ 0, 0, pf_error_as_integer, "_error_as_integer" }, { 0, 0, pf_error_as_integer, "_error_as_integer" },
{ 0, 0, pf_error_as_string, "_error_as_string" }, { 0, 0, pf_error_as_string, "_error_as_string" },

View File

@ -486,67 +486,6 @@ if (mask & STIX_LOG_GC) return; /* don't show gc logs */
/* ========================================================================= */ /* ========================================================================= */
static char* syntax_error_msg[] =
{
"no error",
"illegal character",
"comment not closed",
"string not closed",
"no character after $",
"no valid character after #",
"wrong character literal",
"colon expected",
"string expected",
"invalid radix",
"invalid numeric literal",
"byte too small or too large",
"{ expected",
"} expected",
"( expected",
") expected",
"] expected",
". expected",
", expected",
"| expected",
"> expected",
":= expected",
"identifier expected",
"integer expected",
"primitive: expected",
"wrong directive",
"undefined class",
"duplicate class",
"contradictory class definition",
"#dcl not allowed",
"wrong method name",
"duplicate method name",
"duplicate argument name",
"duplicate temporary variable name",
"duplicate variable name",
"duplicate block argument name",
"cannot assign to argument",
"undeclared variable",
"unusable variable in compiled code",
"inaccessible variable",
"ambiguous variable",
"wrong expression primary",
"too many temporaries",
"too many arguments",
"too many block temporaries",
"too many block arguments",
"too large block",
"wrong primitive function number",
"wrong primitive function identifier",
"wrong module name",
"#include error",
"wrong namespace name",
"wrong pool dictionary name",
"duplicate pool dictionary name",
"literal expected"
};
/* ========================================================================= */
static stix_ooch_t str_my_object[] = { 'M', 'y', 'O', 'b','j','e','c','t' }; static stix_ooch_t str_my_object[] = { 'M', 'y', 'O', 'b','j','e','c','t' };
static stix_ooch_t str_main[] = { 'm', 'a', 'i', 'n' }; static stix_ooch_t str_main[] = { 'm', 'a', 'i', 'n' };
static stix_t* g_stix = STIX_NULL; static stix_t* g_stix = STIX_NULL;
@ -760,9 +699,15 @@ int main (int argc, char* argv[])
} }
printf ("syntax error at line %lu column %lu - %s", printf ("syntax error at line %lu column %lu - ",
(unsigned long int)synerr.loc.line, (unsigned long int)synerr.loc.colm, (unsigned long int)synerr.loc.line, (unsigned long int)synerr.loc.colm);
syntax_error_msg[synerr.num]);
bcslen = STIX_COUNTOF(bcs);
if (stix_convootobcstr (stix, stix_synerrnumtoerrstr(synerr.num), &ucslen, bcs, &bcslen) >= 0)
{
printf (" [%.*s]", (int)bcslen, bcs);
}
if (synerr.tgt.len > 0) if (synerr.tgt.len > 0)
{ {
bcslen = STIX_COUNTOF(bcs); bcslen = STIX_COUNTOF(bcs);

View File

@ -229,23 +229,6 @@
/* ========================================================================= */ /* ========================================================================= */
/* SOURCE CODE I/O FOR COMPILER */ /* SOURCE CODE I/O FOR COMPILER */
/* ========================================================================= */ /* ========================================================================= */
enum stix_iocmd_t
{
STIX_IO_OPEN,
STIX_IO_CLOSE,
STIX_IO_READ
};
typedef enum stix_iocmd_t stix_iocmd_t;
struct stix_ioloc_t
{
unsigned long int line; /**< line */
unsigned long int colm; /**< column */
const stix_ooch_t* file; /**< file specified in #include */
};
typedef struct stix_ioloc_t stix_ioloc_t;
struct stix_iolxc_t struct stix_iolxc_t
{ {
stix_ooci_t c; /**< character */ stix_ooci_t c; /**< character */
@ -260,7 +243,6 @@ enum stix_ioarg_flag_t
}; };
typedef enum stix_ioarg_flag_t stix_ioarg_flag_t; */ typedef enum stix_ioarg_flag_t stix_ioarg_flag_t; */
typedef struct stix_ioarg_t stix_ioarg_t;
struct stix_ioarg_t struct stix_ioarg_t
{ {
/** /**
@ -305,23 +287,19 @@ struct stix_ioarg_t
/*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/
}; };
typedef stix_ooi_t (*stix_ioimpl_t) (
stix_t* stix,
stix_iocmd_t cmd,
stix_ioarg_t* arg
);
struct stix_iotok_t struct stix_iotok_t
{ {
enum enum
{ {
STIX_IOTOK_EOF, STIX_IOTOK_EOF,
STIX_IOTOK_ERRLIT,
STIX_IOTOK_CHARLIT, STIX_IOTOK_CHARLIT,
STIX_IOTOK_STRLIT, STIX_IOTOK_STRLIT,
STIX_IOTOK_SYMLIT, STIX_IOTOK_SYMLIT,
STIX_IOTOK_NUMLIT, STIX_IOTOK_NUMLIT,
STIX_IOTOK_RADNUMLIT, STIX_IOTOK_RADNUMLIT,
STIX_IOTOK_ERRLIT, /* error(NN) */
STIX_IOTOK_ERROR, /* error */
STIX_IOTOK_NIL, STIX_IOTOK_NIL,
STIX_IOTOK_SELF, STIX_IOTOK_SELF,
STIX_IOTOK_SUPER, STIX_IOTOK_SUPER,
@ -356,81 +334,12 @@ struct stix_iotok_t
}; };
typedef struct stix_iotok_t stix_iotok_t; typedef struct stix_iotok_t stix_iotok_t;
enum stix_synerrnum_t
{
STIX_SYNERR_NOERR,
STIX_SYNERR_ILCHR, /* illegal character */
STIX_SYNERR_CMTNC, /* comment not closed */
STIX_SYNERR_STRNC, /* string not closed */
STIX_SYNERR_CLTNT, /* character literal not terminated */
STIX_SYNERR_HLTNT, /* hased literal not terminated */
STIX_SYNERR_CHARLIT, /* wrong character literal */
STIX_SYNERR_COLON, /* : expected */
STIX_SYNERR_STRING, /* string expected */
STIX_SYNERR_RADIX, /* invalid radix */
STIX_SYNERR_RADNUMLIT, /* invalid numeric literal with radix */
STIX_SYNERR_BYTERANGE, /* byte too small or too large */
STIX_SYNERR_LBRACE, /* { expected */
STIX_SYNERR_RBRACE, /* } expected */
STIX_SYNERR_LPAREN, /* ( expected */
STIX_SYNERR_RPAREN, /* ) expected */
STIX_SYNERR_RBRACK, /* ] expected */
STIX_SYNERR_PERIOD, /* . expected */
STIX_SYNERR_COMMA, /* , expected */
STIX_SYNERR_VBAR, /* | expected */
STIX_SYNERR_GT, /* > expected */
STIX_SYNERR_ASSIGN, /* := expected */
STIX_SYNERR_IDENT, /* identifier expected */
STIX_SYNERR_INTEGER, /* integer expected */
STIX_SYNERR_PRIMITIVE, /* primitive: expected */
STIX_SYNERR_DIRECTIVE, /* wrong directive */
STIX_SYNERR_CLASSUNDEF, /* undefined class */
STIX_SYNERR_CLASSDUP, /* duplicate class */
STIX_SYNERR_CLASSCONTRA, /* contradictory class */
STIX_SYNERR_DCLBANNED, /* #dcl not allowed */
STIX_SYNERR_MTHNAME, /* wrong method name */
STIX_SYNERR_MTHNAMEDUP, /* duplicate method name */
STIX_SYNERR_ARGNAMEDUP, /* duplicate argument name */
STIX_SYNERR_TMPRNAMEDUP, /* duplicate temporary variable name */
STIX_SYNERR_VARNAMEDUP, /* duplicate variable name */
STIX_SYNERR_BLKARGNAMEDUP, /* duplicate block argument name */
STIX_SYNERR_VARARG, /* cannot assign to argument */
STIX_SYNERR_VARUNDCL, /* undeclared variable */
STIX_SYNERR_VARUNUSE, /* unsuable variable in compiled code */
STIX_SYNERR_VARINACC, /* inaccessible variable - e.g. accessing an instance variable from a class method is not allowed. */
STIX_SYNERR_VARAMBIG, /* ambiguious variable - e.g. the variable is found in multiple pool dictionaries imported */
STIX_SYNERR_PRIMARY, /* wrong expression primary */
STIX_SYNERR_TMPRFLOOD, /* too many temporaries */
STIX_SYNERR_ARGFLOOD, /* too many arguments */
STIX_SYNERR_BLKTMPRFLOOD, /* too many block temporaries */
STIX_SYNERR_BLKARGFLOOD, /* too many block arguments */
STIX_SYNERR_BLKFLOOD, /* too large block */
STIX_SYNERR_PFNUM, /* wrong primitive number */
STIX_SYNERR_PFID, /* wrong primitive identifier */
STIX_SYNERR_MODNAME, /* wrong module name */
STIX_SYNERR_INCLUDE, /* #include error */
STIX_SYNERR_NAMESPACE, /* wrong namespace name */
STIX_SYNERR_POOLDIC, /* wrong pool dictionary */
STIX_SYNERR_POOLDICDUP, /* duplicate pool dictionary */
STIX_SYNERR_LITERAL /* literal expected */
};
typedef enum stix_synerrnum_t stix_synerrnum_t;
typedef struct stix_iolink_t stix_iolink_t; typedef struct stix_iolink_t stix_iolink_t;
struct stix_iolink_t struct stix_iolink_t
{ {
stix_iolink_t* link; stix_iolink_t* link;
}; };
struct stix_synerr_t
{
stix_synerrnum_t num;
stix_ioloc_t loc;
stix_oocs_t tgt;
};
typedef struct stix_synerr_t stix_synerr_t;
struct stix_code_t struct stix_code_t
{ {
stix_uint8_t* ptr; stix_uint8_t* ptr;
@ -1224,19 +1133,6 @@ stix_oop_t stix_inttostr (
int radix int radix
); );
/* ========================================================================= */
/* comp.c */
/* ========================================================================= */
STIX_EXPORT int stix_compile (
stix_t* stix,
stix_ioimpl_t io
);
STIX_EXPORT void stix_getsynerr (
stix_t* stix,
stix_synerr_t* synerr
);
/* ========================================================================= */ /* ========================================================================= */
/* exec.c */ /* exec.c */
/* ========================================================================= */ /* ========================================================================= */

View File

@ -1024,6 +1024,101 @@ typedef enum stix_log_mask_t stix_log_mask_t;
#endif #endif
#if defined(STIX_INCLUDE_COMPILER)
enum stix_iocmd_t
{
STIX_IO_OPEN,
STIX_IO_CLOSE,
STIX_IO_READ
};
typedef enum stix_iocmd_t stix_iocmd_t;
struct stix_ioloc_t
{
unsigned long int line; /**< line */
unsigned long int colm; /**< column */
const stix_ooch_t* file; /**< file specified in #include */
};
typedef struct stix_ioloc_t stix_ioloc_t;
typedef struct stix_ioarg_t stix_ioarg_t;
typedef stix_ooi_t (*stix_ioimpl_t) (
stix_t* stix,
stix_iocmd_t cmd,
stix_ioarg_t* arg
);
enum stix_synerrnum_t
{
STIX_SYNERR_NOERR,
STIX_SYNERR_ILCHR, /* illegal character */
STIX_SYNERR_CMTNC, /* comment not closed */
STIX_SYNERR_STRNC, /* string not closed */
STIX_SYNERR_CLTNT, /* character literal not terminated */
STIX_SYNERR_HLTNT, /* hased literal not terminated */
STIX_SYNERR_CHARLIT, /* wrong character literal */
STIX_SYNERR_COLON, /* : expected */
STIX_SYNERR_STRING, /* string expected */
STIX_SYNERR_RADIX, /* invalid radix */
STIX_SYNERR_RADNUMLIT, /* invalid numeric literal with radix */
STIX_SYNERR_BYTERANGE, /* byte too small or too large */
STIX_SYNERR_ERRLIT, /* wrong error literal */
STIX_SYNERR_LBRACE, /* { expected */
STIX_SYNERR_RBRACE, /* } expected */
STIX_SYNERR_LPAREN, /* ( expected */
STIX_SYNERR_RPAREN, /* ) expected */
STIX_SYNERR_RBRACK, /* ] expected */
STIX_SYNERR_PERIOD, /* . expected */
STIX_SYNERR_COMMA, /* , expected */
STIX_SYNERR_VBAR, /* | expected */
STIX_SYNERR_GT, /* > expected */
STIX_SYNERR_ASSIGN, /* := expected */
STIX_SYNERR_IDENT, /* identifier expected */
STIX_SYNERR_INTEGER, /* integer expected */
STIX_SYNERR_PRIMITIVE, /* primitive: expected */
STIX_SYNERR_DIRECTIVE, /* wrong directive */
STIX_SYNERR_CLASSUNDEF, /* undefined class */
STIX_SYNERR_CLASSDUP, /* duplicate class */
STIX_SYNERR_CLASSCONTRA, /* contradictory class */
STIX_SYNERR_DCLBANNED, /* #dcl not allowed */
STIX_SYNERR_MTHNAME, /* wrong method name */
STIX_SYNERR_MTHNAMEDUP, /* duplicate method name */
STIX_SYNERR_ARGNAMEDUP, /* duplicate argument name */
STIX_SYNERR_TMPRNAMEDUP, /* duplicate temporary variable name */
STIX_SYNERR_VARNAMEDUP, /* duplicate variable name */
STIX_SYNERR_BLKARGNAMEDUP, /* duplicate block argument name */
STIX_SYNERR_VARARG, /* cannot assign to argument */
STIX_SYNERR_VARUNDCL, /* undeclared variable */
STIX_SYNERR_VARUNUSE, /* unsuable variable in compiled code */
STIX_SYNERR_VARINACC, /* inaccessible variable - e.g. accessing an instance variable from a class method is not allowed. */
STIX_SYNERR_VARAMBIG, /* ambiguious variable - e.g. the variable is found in multiple pool dictionaries imported */
STIX_SYNERR_PRIMARY, /* wrong expression primary */
STIX_SYNERR_TMPRFLOOD, /* too many temporaries */
STIX_SYNERR_ARGFLOOD, /* too many arguments */
STIX_SYNERR_BLKTMPRFLOOD, /* too many block temporaries */
STIX_SYNERR_BLKARGFLOOD, /* too many block arguments */
STIX_SYNERR_BLKFLOOD, /* too large block */
STIX_SYNERR_PFNUM, /* wrong primitive number */
STIX_SYNERR_PFID, /* wrong primitive identifier */
STIX_SYNERR_MODNAME, /* wrong module name */
STIX_SYNERR_INCLUDE, /* #include error */
STIX_SYNERR_NAMESPACE, /* wrong namespace name */
STIX_SYNERR_POOLDIC, /* wrong pool dictionary */
STIX_SYNERR_POOLDICDUP, /* duplicate pool dictionary */
STIX_SYNERR_LITERAL /* literal expected */
};
typedef enum stix_synerrnum_t stix_synerrnum_t;
struct stix_synerr_t
{
stix_synerrnum_t num;
stix_ioloc_t loc;
stix_oocs_t tgt;
};
typedef struct stix_synerr_t stix_synerr_t;
#endif
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { extern "C" {
#endif #endif
@ -1321,6 +1416,23 @@ STIX_EXPORT const stix_ooch_t* stix_errnumtoerrstr (
stix_errnum_t errnum stix_errnum_t errnum
); );
#if defined(STIX_INCLUDE_COMPILER)
STIX_EXPORT int stix_compile (
stix_t* stix,
stix_ioimpl_t io
);
STIX_EXPORT void stix_getsynerr (
stix_t* stix,
stix_synerr_t* synerr
);
STIX_EXPORT const stix_ooch_t* stix_synerrnumtoerrstr (
stix_synerrnum_t errnum
);
#endif
#if defined(__cplusplus) #if defined(__cplusplus)
} }
#endif #endif