2015-05-15 14:55:12 +00:00
/*
* $ Id $
*
2016-02-12 16:23:26 +00:00
Copyright ( c ) 2014 - 2016 Chung , Hyung - Hwan . All rights reserved .
2015-05-15 14:55:12 +00:00
Redistribution and use in source and binary forms , with or without
modification , are permitted provided that the following conditions
are met :
1. Redistributions of source code must retain the above copyright
notice , this list of conditions and the following disclaimer .
2. Redistributions in binary form must reproduce the above copyright
notice , this list of conditions and the following disclaimer in the
documentation and / or other materials provided with the distribution .
THIS SOFTWARE IS PROVIDED BY THE AUTHOR " AS IS " AND ANY EXPRESS OR
2015-06-03 17:24:11 +00:00
IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WAfRRANTIES
2015-05-15 14:55:12 +00:00
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED .
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT , INDIRECT ,
INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT
NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*/
# include "stix-prv.h"
2016-05-12 05:53:35 +00:00
# define CLASS_BUFFER_ALIGN 64
# define LITERAL_BUFFER_ALIGN 64
# define CODE_BUFFER_ALIGN 64
# define BALIT_BUFFER_ALIGN 64
# define ARLIT_BUFFER_ALIGN 64
# define BLK_TMPRCNT_BUFFER_ALIGN 32
# define POOLDIC_OOP_BUFFER_ALIGN 32
2015-05-31 16:44:56 +00:00
/* initial method dictionary size */
# define INSTANCE_METHOD_DICTIONARY_SIZE 256 /* TODO: choose the right size */
2015-05-31 18:43:37 +00:00
# define CLASS_METHOD_DICTIONARY_SIZE 128 /* TODO: choose the right size */
2015-07-12 17:14:21 +00:00
# define NAMESPACE_SIZE 128 /* TODO: choose the right size */
2015-07-14 13:35:18 +00:00
# define POOL_DICTIONARY_SIZE_ALIGN 128
2015-05-19 15:16:18 +00:00
2015-05-22 15:09:45 +00:00
enum class_mod_t
{
2015-07-06 13:27:49 +00:00
CLASS_INDEXED = ( 1 < < 0 )
2015-05-22 15:09:45 +00:00
} ;
2015-05-31 16:44:56 +00:00
enum mth_type_t
2015-05-22 15:09:45 +00:00
{
2015-05-31 16:44:56 +00:00
MTH_INSTANCE ,
MTH_CLASS
2015-05-22 15:09:45 +00:00
} ;
2015-05-27 17:16:50 +00:00
enum var_type_t
{
2015-06-03 17:24:11 +00:00
/* NEVER Change the order and the value of 3 items below.
* stix - > c - > cls . vars and stix - > c - > cls . var_count relies on them . */
VAR_INSTANCE = 0 ,
VAR_CLASS = 1 ,
VAR_CLASSINST = 2 ,
/* NEVER Change the order and the value of 3 items above. */
VAR_GLOBAL ,
2015-06-03 04:22:19 +00:00
VAR_ARGUMENT ,
2015-06-03 17:24:11 +00:00
VAR_TEMPORARY
2015-05-27 17:16:50 +00:00
} ;
typedef enum var_type_t var_type_t ;
struct var_info_t
{
2015-06-30 14:47:39 +00:00
var_type_t type ;
2016-08-29 06:10:02 +00:00
stix_ooi_t pos ; /* not used for VAR_GLOBAL */
2015-06-30 14:47:39 +00:00
stix_oop_class_t cls ; /* useful if type is VAR_CLASS. note STIX_NULL indicates the self class. */
stix_oop_association_t gbl ; /* used for VAR_GLOBAL only */
2015-05-27 17:16:50 +00:00
} ;
typedef struct var_info_t var_info_t ;
2015-06-03 17:24:11 +00:00
static struct voca_t
2015-05-21 17:07:55 +00:00
{
stix_oow_t len ;
2015-10-28 14:58:58 +00:00
stix_ooch_t str [ 11 ] ;
2015-06-03 17:24:11 +00:00
} vocas [ ] = {
2015-05-21 17:07:55 +00:00
{ 4 , { ' b ' , ' y ' , ' t ' , ' e ' } } ,
{ 9 , { ' c ' , ' h ' , ' a ' , ' r ' , ' a ' , ' c ' , ' t ' , ' e ' , ' r ' } } ,
{ 5 , { ' c ' , ' l ' , ' a ' , ' s ' , ' s ' } } ,
{ 9 , { ' c ' , ' l ' , ' a ' , ' s ' , ' s ' , ' i ' , ' n ' , ' s ' , ' t ' } } ,
{ 3 , { ' d ' , ' c ' , ' l ' } } ,
{ 7 , { ' d ' , ' e ' , ' c ' , ' l ' , ' a ' , ' r ' , ' e ' } } ,
2016-06-22 03:23:14 +00:00
{ 6 , { ' e ' , ' n ' , ' s ' , ' u ' , ' r ' , ' e ' , } } ,
2016-03-28 13:25:36 +00:00
{ 9 , { ' e ' , ' x ' , ' c ' , ' e ' , ' p ' , ' t ' , ' i ' , ' o ' , ' n ' } } ,
2015-07-06 13:27:49 +00:00
{ 6 , { ' e ' , ' x ' , ' t ' , ' e ' , ' n ' , ' d ' } } ,
2015-05-21 17:07:55 +00:00
{ 5 , { ' f ' , ' a ' , ' l ' , ' s ' , ' e ' } } ,
2015-10-29 15:24:46 +00:00
{ 8 , { ' h ' , ' a ' , ' l ' , ' f ' , ' w ' , ' o ' , ' r ' , ' d ' } } ,
2015-05-21 17:07:55 +00:00
{ 7 , { ' i ' , ' n ' , ' c ' , ' l ' , ' u ' , ' d ' , ' e ' } } ,
2015-11-17 14:13:59 +00:00
{ 6 , { ' l ' , ' i ' , ' w ' , ' o ' , ' r ' , ' d ' } } ,
2015-05-21 17:07:55 +00:00
{ 4 , { ' m ' , ' a ' , ' i ' , ' n ' } } ,
2015-05-27 17:16:50 +00:00
{ 6 , { ' m ' , ' e ' , ' t ' , ' h ' , ' o ' , ' d ' } } ,
{ 3 , { ' m ' , ' t ' , ' h ' } } ,
2015-05-25 17:10:49 +00:00
{ 3 , { ' n ' , ' i ' , ' l ' } } ,
2015-05-21 17:07:55 +00:00
{ 7 , { ' p ' , ' o ' , ' i ' , ' n ' , ' t ' , ' e ' , ' r ' } } ,
2015-07-14 13:35:18 +00:00
{ 7 , { ' p ' , ' o ' , ' o ' , ' l ' , ' d ' , ' i ' , ' c ' } } ,
2015-05-22 15:09:45 +00:00
{ 10 , { ' p ' , ' r ' , ' i ' , ' m ' , ' i ' , ' t ' , ' i ' , ' v ' , ' e ' , ' : ' } } ,
2015-05-21 17:07:55 +00:00
{ 4 , { ' s ' , ' e ' , ' l ' , ' f ' } } ,
{ 5 , { ' s ' , ' u ' , ' p ' , ' e ' , ' r ' } } ,
{ 11 , { ' t ' , ' h ' , ' i ' , ' s ' , ' C ' , ' o ' , ' n ' , ' t ' , ' e ' , ' x ' , ' t ' } } ,
2016-07-05 15:22:29 +00:00
{ 11 , { ' t ' , ' h ' , ' i ' , ' s ' , ' P ' , ' r ' , ' o ' , ' c ' , ' e ' , ' s ' , ' s ' } } ,
2015-05-21 17:07:55 +00:00
{ 4 , { ' t ' , ' r ' , ' u ' , ' e ' } } ,
2015-05-22 15:09:45 +00:00
{ 4 , { ' w ' , ' o ' , ' r ' , ' d ' } } ,
2015-06-03 17:24:11 +00:00
2015-05-22 15:09:45 +00:00
{ 1 , { ' | ' } } ,
{ 1 , { ' > ' } } ,
2015-06-03 17:24:11 +00:00
{ 1 , { ' < ' } } ,
2015-05-21 17:07:55 +00:00
2015-06-03 17:24:11 +00:00
{ 5 , { ' < ' , ' E ' , ' O ' , ' F ' , ' > ' } }
2015-05-21 17:07:55 +00:00
} ;
2015-06-03 17:24:11 +00:00
enum voca_id_t
{
VOCA_BYTE ,
VOCA_CHARACTER ,
VOCA_CLASS ,
VOCA_CLASSINST ,
VOCA_DCL ,
VOCA_DECLARE ,
2016-06-22 03:23:14 +00:00
VOCA_ENSURE ,
2016-03-28 13:25:36 +00:00
VOCA_EXCEPTION ,
2015-07-06 13:27:49 +00:00
VOCA_EXTEND ,
2015-06-03 17:24:11 +00:00
VOCA_FALSE ,
2015-10-29 15:24:46 +00:00
VOCA_HALFWORD ,
2015-06-03 17:24:11 +00:00
VOCA_INCLUDE ,
2015-11-17 14:13:59 +00:00
VOCA_LIWORD ,
2015-06-03 17:24:11 +00:00
VOCA_MAIN ,
VOCA_METHOD ,
VOCA_MTH ,
VOCA_NIL ,
VOCA_POINTER ,
2015-07-14 13:35:18 +00:00
VOCA_POOLDIC ,
2015-06-03 17:24:11 +00:00
VOCA_PRIMITIVE_COLON ,
VOCA_SELF ,
VOCA_SUPER ,
VOCA_THIS_CONTEXT ,
2016-07-05 15:22:29 +00:00
VOCA_THIS_PROCESS ,
2015-06-03 17:24:11 +00:00
VOCA_TRUE ,
VOCA_WORD ,
VOCA_VBAR ,
VOCA_GT ,
VOCA_LT ,
VOCA_EOF
} ;
typedef enum voca_id_t voca_id_t ;
2015-06-01 16:59:07 +00:00
2015-06-20 03:07:11 +00:00
static int compile_block_statement ( stix_t * stix ) ;
2015-06-16 13:29:29 +00:00
static int compile_method_statement ( stix_t * stix ) ;
static int compile_method_expression ( stix_t * stix , int pop ) ;
2015-12-17 16:11:10 +00:00
static int add_literal ( stix_t * stix , stix_oop_t lit , stix_oow_t * index ) ;
2015-05-15 14:55:12 +00:00
2015-10-28 14:58:58 +00:00
static STIX_INLINE int is_spacechar ( stix_ooci_t c )
2015-05-15 14:55:12 +00:00
{
2015-05-19 15:16:18 +00:00
/* TODO: handle other space unicode characters */
switch ( c )
2015-05-15 14:55:12 +00:00
{
2015-05-19 15:16:18 +00:00
case ' ' :
case ' \f ' : /* formfeed */
case ' \n ' : /* linefeed */
case ' \r ' : /* carriage return */
case ' \t ' : /* horizon tab */
case ' \v ' : /* vertical tab */
return 1 ;
2015-05-15 14:55:12 +00:00
2015-05-19 15:16:18 +00:00
default :
return 0 ;
2015-05-15 14:55:12 +00:00
}
}
2015-10-03 15:29:03 +00:00
2015-10-28 14:58:58 +00:00
static STIX_INLINE int is_alphachar ( stix_ooci_t c )
2015-05-15 14:55:12 +00:00
{
2015-05-19 15:16:18 +00:00
/* TODO: support full unicode */
return ( c > = ' a ' & & c < = ' z ' ) | | ( c > = ' A ' & & c < = ' Z ' ) ;
}
2015-05-15 14:55:12 +00:00
2015-10-28 14:58:58 +00:00
static STIX_INLINE int is_digitchar ( stix_ooci_t c )
2015-05-19 15:16:18 +00:00
{
/* TODO: support full unicode */
return ( c > = ' 0 ' & & c < = ' 9 ' ) ;
2015-05-15 14:55:12 +00:00
}
2015-10-28 14:58:58 +00:00
static STIX_INLINE int is_alnumchar ( stix_ooci_t c )
2015-05-19 15:16:18 +00:00
{
/* TODO: support full unicode */
return ( c > = ' a ' & & c < = ' z ' ) | | ( c > = ' A ' & & c < = ' Z ' ) | | ( c > = ' 0 ' & & c < = ' 9 ' ) ;
}
2015-05-15 14:55:12 +00:00
2015-10-28 14:58:58 +00:00
static STIX_INLINE int is_binselchar ( stix_ooci_t c )
2015-05-15 14:55:12 +00:00
{
/*
2015-05-20 14:27:47 +00:00
* binary - selector - character : =
2015-05-15 14:55:12 +00:00
* ' ! ' | ' % ' | ' & ' | ' * ' | ' + ' | ' , ' |
* ' / ' | ' < ' | ' > ' | ' = ' | ' ? ' | ' @ ' |
* ' \ ' | ' ~ ' | ' | ' | ' - '
*/
switch ( c )
{
2015-05-19 15:16:18 +00:00
case ' ! ' :
case ' % ' :
case ' & ' :
case ' * ' :
case ' + ' :
case ' , ' :
case ' / ' :
case ' < ' :
case ' > ' :
case ' = ' :
case ' ? ' :
case ' @ ' :
case ' \\ ' :
case ' | ' :
case ' ~ ' :
case ' - ' :
2015-05-15 14:55:12 +00:00
return 1 ;
2015-05-19 15:16:18 +00:00
2015-05-15 14:55:12 +00:00
default :
return 0 ;
}
}
2015-10-28 14:58:58 +00:00
static STIX_INLINE int is_leadidentchar ( stix_ooci_t c )
2015-10-03 15:29:03 +00:00
{
return is_alphachar ( c ) | | c = = ' _ ' ;
}
2015-10-28 14:58:58 +00:00
static STIX_INLINE int is_identchar ( stix_ooci_t c )
2015-10-03 15:29:03 +00:00
{
return is_alnumchar ( c ) | | c = = ' _ ' ;
}
2015-10-28 14:58:58 +00:00
static STIX_INLINE int is_closing_char ( stix_ooci_t c )
2015-05-15 14:55:12 +00:00
{
2015-05-19 15:16:18 +00:00
switch ( c )
{
case ' . ' :
case ' ] ' :
case ' ) ' :
case ' ; ' :
case ' \" ' :
case ' \' ' :
return 1 ;
default :
return 0 ;
}
2015-05-15 14:55:12 +00:00
}
2015-10-28 14:58:58 +00:00
static STIX_INLINE int is_word ( const stix_oocs_t * ucs , voca_id_t id )
2015-07-13 15:35:52 +00:00
{
return ucs - > len = = vocas [ id ] . len & & stix_equalchars ( ucs - > ptr , vocas [ id ] . str , vocas [ id ] . len ) ;
}
2015-10-28 14:58:58 +00:00
static int is_reserved_word ( const stix_oocs_t * ucs )
2015-07-13 15:35:52 +00:00
{
static int rw [ ] =
{
VOCA_SELF ,
VOCA_SUPER ,
VOCA_NIL ,
VOCA_TRUE ,
VOCA_FALSE ,
2016-07-05 15:22:29 +00:00
VOCA_THIS_CONTEXT ,
VOCA_THIS_PROCESS
2015-07-13 15:35:52 +00:00
} ;
int i ;
for ( i = 0 ; i < STIX_COUNTOF ( rw ) ; i + + )
{
if ( is_word ( ucs , rw [ i ] ) ) return 1 ;
}
return 0 ;
}
2016-09-06 16:06:22 +00:00
static int begin_include ( stix_t * stix ) ;
static int end_include ( stix_t * stix ) ;
2015-05-25 17:10:49 +00:00
2015-10-28 14:58:58 +00:00
static void set_syntax_error ( stix_t * stix , stix_synerrnum_t num , const stix_ioloc_t * loc , const stix_oocs_t * tgt )
2015-05-25 17:10:49 +00:00
{
stix - > errnum = STIX_ESYNTAX ;
stix - > c - > synerr . num = num ;
2015-11-17 14:13:59 +00:00
/* The SCO compiler complains of this ternary operation saying:
* error : operands have incompatible types : op " : "
* it seems to complain of type mismatch between * loc and
* stix - > c - > tok . loc due to ' const ' prefixed to loc . */
/*stix->c->synerr.loc = loc? *loc: stix->c->tok.loc;*/
if ( loc )
stix - > c - > synerr . loc = * loc ;
else
stix - > c - > synerr . loc = stix - > c - > tok . loc ;
2015-05-25 17:10:49 +00:00
if ( tgt ) stix - > c - > synerr . tgt = * tgt ;
else
{
stix - > c - > synerr . tgt . ptr = STIX_NULL ;
stix - > c - > synerr . tgt . len = 0 ;
}
}
2015-12-17 16:11:10 +00:00
static int copy_string_to ( stix_t * stix , const stix_oocs_t * src , stix_oocs_t * dst , stix_oow_t * dst_capa , int append , stix_ooch_t add_delim )
2015-05-25 17:10:49 +00:00
{
2015-12-17 16:11:10 +00:00
stix_oow_t len , pos ;
2015-05-25 17:10:49 +00:00
if ( append )
{
pos = dst - > len ;
len = dst - > len + src - > len ;
2015-05-31 16:44:56 +00:00
if ( add_delim ! = ' \0 ' ) len + + ;
2015-05-25 17:10:49 +00:00
}
else
{
pos = 0 ;
len = src - > len ;
}
if ( len > * dst_capa )
{
2015-10-28 14:58:58 +00:00
stix_ooch_t * tmp ;
2015-12-17 16:11:10 +00:00
stix_oow_t capa ;
2015-05-25 17:10:49 +00:00
capa = STIX_ALIGN ( len , CLASS_BUFFER_ALIGN ) ;
tmp = stix_reallocmem ( stix , dst - > ptr , STIX_SIZEOF ( * tmp ) * capa ) ;
if ( ! tmp ) return - 1 ;
dst - > ptr = tmp ;
* dst_capa = capa ;
}
2015-05-31 16:44:56 +00:00
if ( append & & add_delim ) dst - > ptr [ pos + + ] = add_delim ;
2015-10-28 14:58:58 +00:00
stix_copyoochars ( & dst - > ptr [ pos ] , src - > ptr , src - > len ) ;
2015-05-25 17:10:49 +00:00
dst - > len = len ;
return 0 ;
}
2015-12-17 16:11:10 +00:00
static int find_word_in_string ( const stix_oocs_t * haystack , const stix_oocs_t * name , stix_oow_t * xindex )
2015-05-25 17:10:49 +00:00
{
/* this function is inefficient. but considering the typical number
* of arguments and temporary variables , the inefficiency can be
* ignored in my opinion . the overhead to maintain the reverse lookup
* table from a name to an index should be greater than this simple
* inefficient lookup */
2015-10-28 14:58:58 +00:00
stix_ooch_t * t , * e ;
2015-12-17 16:11:10 +00:00
stix_oow_t index , i ;
2015-05-25 17:10:49 +00:00
t = haystack - > ptr ;
e = t + haystack - > len ;
index = 0 ;
while ( t < e )
{
while ( t < e & & is_spacechar ( * t ) ) t + + ;
for ( i = 0 ; i < name - > len ; i + + )
{
if ( t > = e | | name - > ptr [ i ] ! = * t ) goto unmatched ;
t + + ;
}
2015-07-15 02:36:24 +00:00
if ( t > = e | | is_spacechar ( * t ) )
{
if ( xindex ) * xindex = index ;
return 0 ;
}
2015-05-25 17:10:49 +00:00
unmatched :
while ( t < e )
{
if ( is_spacechar ( * t ) )
{
t + + ;
break ;
}
t + + ;
}
index + + ;
}
return - 1 ;
}
2015-06-16 04:31:28 +00:00
# define CHAR_TO_NUM(c,base) \
( ( c > = ' 0 ' & & c < = ' 9 ' ) ? ( ( c - ' 0 ' < base ) ? ( c - ' 0 ' ) : base ) : \
( c > = ' A ' & & c < = ' Z ' ) ? ( ( c - ' A ' + 10 < base ) ? ( c - ' A ' + 10 ) : base ) : \
( c > = ' a ' & & c < = ' z ' ) ? ( ( c - ' a ' + 10 < base ) ? ( c - ' a ' + 10 ) : base ) : base )
2016-09-06 16:06:22 +00:00
static int string_to_smooi ( stix_t * stix , stix_oocs_t * str , int radixed , stix_ooi_t * num )
2015-06-16 04:31:28 +00:00
{
2015-06-16 13:29:29 +00:00
/* it is not a generic conversion function.
* it assumes a certain pre - sanity check on the string
* done by the lexical analyzer */
2015-06-23 14:00:26 +00:00
int v , negsign , base ;
2015-10-28 14:58:58 +00:00
const stix_ooch_t * ptr , * end ;
2015-06-16 04:31:28 +00:00
stix_oow_t value , old_value ;
negsign = 0 ;
ptr = str - > ptr ,
end = str - > ptr + str - > len ;
2015-06-16 13:29:29 +00:00
STIX_ASSERT ( ptr < end ) ;
if ( * ptr = = ' + ' | | * ptr = = ' - ' )
{
negsign = * ptr - ' + ' ;
ptr + + ;
}
if ( radixed )
2015-06-16 04:31:28 +00:00
{
2015-06-16 13:29:29 +00:00
STIX_ASSERT ( ptr < end ) ;
base = 0 ;
do
2015-06-16 04:31:28 +00:00
{
2015-06-16 13:29:29 +00:00
base = base * 10 + CHAR_TO_NUM ( * ptr , 10 ) ;
2015-06-16 04:31:28 +00:00
ptr + + ;
}
2015-06-16 13:29:29 +00:00
while ( * ptr ! = ' r ' ) ;
2015-06-16 04:31:28 +00:00
2015-06-16 13:29:29 +00:00
ptr + + ;
2015-06-16 04:31:28 +00:00
}
2015-06-16 13:29:29 +00:00
else base = 10 ;
STIX_ASSERT ( ptr < end ) ;
2015-06-16 04:31:28 +00:00
value = old_value = 0 ;
2015-06-16 13:29:29 +00:00
while ( ptr < end & & ( v = CHAR_TO_NUM ( * ptr , base ) ) < base )
2015-06-16 04:31:28 +00:00
{
value = value * base + v ;
if ( value < old_value )
{
/* overflow must have occurred */
2015-06-23 14:00:26 +00:00
stix - > errnum = STIX_ERANGE ;
return - 1 ;
2015-06-16 04:31:28 +00:00
}
old_value = value ;
ptr + + ;
}
2015-06-23 14:00:26 +00:00
if ( ptr < end )
2015-06-16 04:31:28 +00:00
{
2015-06-23 14:00:26 +00:00
/* trailing garbage? */
2015-06-16 04:31:28 +00:00
stix - > errnum = STIX_EINVAL ;
return - 1 ;
}
2015-11-20 09:05:55 +00:00
STIX_ASSERT ( - STIX_SMOOI_MAX = = STIX_SMOOI_MIN ) ;
if ( value > STIX_SMOOI_MAX )
2015-06-16 04:31:28 +00:00
{
2015-11-20 09:05:55 +00:00
stix - > errnum = STIX_ERANGE ;
return - 1 ;
2015-06-16 04:31:28 +00:00
}
2015-11-20 09:05:55 +00:00
* num = value ;
if ( negsign ) * num * = - 1 ;
2015-06-16 04:31:28 +00:00
return 0 ;
}
2015-11-12 06:57:35 +00:00
static stix_oop_t string_to_num ( stix_t * stix , stix_oocs_t * str , int radixed )
{
int negsign , base ;
const stix_ooch_t * ptr , * end ;
negsign = 0 ;
ptr = str - > ptr ,
end = str - > ptr + str - > len ;
STIX_ASSERT ( ptr < end ) ;
if ( * ptr = = ' + ' | | * ptr = = ' - ' )
{
negsign = * ptr - ' + ' ;
ptr + + ;
}
if ( radixed )
{
STIX_ASSERT ( ptr < end ) ;
base = 0 ;
do
{
base = base * 10 + CHAR_TO_NUM ( * ptr , 10 ) ;
ptr + + ;
}
while ( * ptr ! = ' r ' ) ;
ptr + + ;
}
else base = 10 ;
/* TODO: handle floating point numbers ... etc */
if ( negsign ) base = - base ;
return stix_strtoint ( stix , ptr , end - ptr , base ) ;
}
2015-05-25 17:10:49 +00:00
/* ---------------------------------------------------------------------
* Tokenizer
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2015-05-19 15:16:18 +00:00
# define GET_CHAR(stix) \
do { if ( get_char ( stix ) < = - 1 ) return - 1 ; } while ( 0 )
# define GET_CHAR_TO(stix,c) \
do { \
if ( get_char ( stix ) < = - 1 ) return - 1 ; \
c = ( stix ) - > c - > lxc . c ; \
} while ( 0 )
# define GET_TOKEN(stix) \
do { if ( get_token ( stix ) < = - 1 ) return - 1 ; } while ( 0 )
2015-05-15 14:55:12 +00:00
2015-06-23 14:00:26 +00:00
# define GET_TOKEN_WITH_ERRRET(stix, v_ret) \
do { if ( get_token ( stix ) < = - 1 ) return v_ret ; } while ( 0 )
2015-05-19 15:16:18 +00:00
# define ADD_TOKEN_STR(stix,s,l) \
do { if ( add_token_str ( stix , s , l ) < = - 1 ) return - 1 ; } while ( 0 )
2015-05-15 14:55:12 +00:00
2015-05-19 15:16:18 +00:00
# define ADD_TOKEN_CHAR(stix,c) \
do { if ( add_token_char ( stix , c ) < = - 1 ) return - 1 ; } while ( 0 )
2015-05-15 14:55:12 +00:00
2016-08-29 07:39:09 +00:00
# define CLEAR_TOKEN_NAME(stix) ((stix)->c->tok.name.len = 0)
# define SET_TOKEN_TYPE(stix,tv) ((stix)->c->tok.type = (tv))
# define TOKEN_TYPE(stix) ((stix)->c->tok.type)
# define TOKEN_NAME(stix) (&(stix)->c->tok.name)
# define TOKEN_NAME_CAPA(stix) ((stix)->c->tok.name_capa)
# define TOKEN_NAME_PTR(stix) ((stix)->c->tok.name.ptr)
# define TOKEN_NAME_LEN(stix) ((stix)->c->tok.name.len)
# define TOKEN_LOC(stix) (&(stix)->c->tok.loc)
# define LEXER_LOC(stix) (&(stix)->c->lxc.l)
static STIX_INLINE int does_token_name_match ( stix_t * stix , voca_id_t id )
{
return stix - > c - > tok . name . len = = vocas [ id ] . len & &
stix_equalchars ( stix - > c - > tok . name . ptr , vocas [ id ] . str , vocas [ id ] . len ) ;
}
static STIX_INLINE int is_token_symbol ( stix_t * stix , voca_id_t id )
{
return TOKEN_TYPE ( stix ) = = STIX_IOTOK_SYMLIT & & does_token_name_match ( stix , id ) ;
}
static STIX_INLINE int is_token_word ( stix_t * stix , voca_id_t id )
{
return TOKEN_TYPE ( stix ) = = STIX_IOTOK_IDENT & & does_token_name_match ( stix , id ) ;
}
static STIX_INLINE int is_token_binary_selector ( stix_t * stix , voca_id_t id )
{
return TOKEN_TYPE ( stix ) = = STIX_IOTOK_BINSEL & & does_token_name_match ( stix , id ) ;
}
static STIX_INLINE int is_token_keyword ( stix_t * stix , voca_id_t id )
{
return TOKEN_TYPE ( stix ) = = STIX_IOTOK_KEYWORD & & does_token_name_match ( stix , id ) ;
}
2015-05-15 14:55:12 +00:00
2015-12-17 16:11:10 +00:00
static STIX_INLINE int add_token_str ( stix_t * stix , const stix_ooch_t * ptr , stix_oow_t len )
2015-05-15 14:55:12 +00:00
{
2015-10-28 14:58:58 +00:00
stix_oocs_t tmp ;
2015-05-15 14:55:12 +00:00
2015-10-28 14:58:58 +00:00
tmp . ptr = ( stix_ooch_t * ) ptr ;
2015-05-25 17:10:49 +00:00
tmp . len = len ;
2016-08-29 07:39:09 +00:00
return copy_string_to ( stix , & tmp , TOKEN_NAME ( stix ) , & TOKEN_NAME_CAPA ( stix ) , 1 , ' \0 ' ) ;
2015-05-15 14:55:12 +00:00
}
2015-05-19 15:16:18 +00:00
2015-10-28 14:58:58 +00:00
static STIX_INLINE int add_token_char ( stix_t * stix , stix_ooch_t c )
2015-05-19 15:16:18 +00:00
{
2015-10-28 14:58:58 +00:00
stix_oocs_t tmp ;
2015-05-25 17:10:49 +00:00
tmp . ptr = & c ;
tmp . len = 1 ;
2016-08-29 07:39:09 +00:00
return copy_string_to ( stix , & tmp , TOKEN_NAME ( stix ) , & TOKEN_NAME_CAPA ( stix ) , 1 , ' \0 ' ) ;
2015-05-19 15:16:18 +00:00
}
static STIX_INLINE void unget_char ( stix_t * stix , const stix_iolxc_t * c )
{
/* Make sure that the unget buffer is large enough */
STIX_ASSERT ( stix - > c - > nungots < STIX_COUNTOF ( stix - > c - > ungot ) ) ;
stix - > c - > ungot [ stix - > c - > nungots + + ] = * c ;
}
2015-05-15 14:55:12 +00:00
2015-05-17 05:02:30 +00:00
static int get_char ( stix_t * stix )
2015-05-15 14:55:12 +00:00
{
2015-12-17 16:11:10 +00:00
stix_ooi_t n ;
2015-10-28 14:58:58 +00:00
stix_ooci_t lc , ec ;
2015-05-15 14:55:12 +00:00
2015-05-19 15:16:18 +00:00
if ( stix - > c - > nungots > 0 )
{
/* something in the unget buffer */
stix - > c - > lxc = stix - > c - > ungot [ - - stix - > c - > nungots ] ;
return 0 ;
}
2015-06-11 12:09:10 +00:00
if ( stix - > c - > curinp - > b . state = = - 1 )
{
stix - > c - > curinp - > b . state = 0 ;
return - 1 ;
}
else if ( stix - > c - > curinp - > b . state = = 1 )
{
stix - > c - > curinp - > b . state = 0 ;
goto return_eof ;
}
2015-05-17 05:02:30 +00:00
if ( stix - > c - > curinp - > b . pos > = stix - > c - > curinp - > b . len )
2015-05-15 14:55:12 +00:00
{
2015-05-17 05:02:30 +00:00
n = stix - > c - > impl ( stix , STIX_IO_READ , stix - > c - > curinp ) ;
2015-05-15 14:55:12 +00:00
if ( n < = - 1 ) return - 1 ;
2015-06-11 12:09:10 +00:00
2015-05-15 14:55:12 +00:00
if ( n = = 0 )
{
2015-06-11 12:09:10 +00:00
return_eof :
2015-05-19 15:16:18 +00:00
stix - > c - > curinp - > lxc . c = STIX_UCI_EOF ;
stix - > c - > curinp - > lxc . l . line = stix - > c - > curinp - > line ;
stix - > c - > curinp - > lxc . l . colm = stix - > c - > curinp - > colm ;
stix - > c - > curinp - > lxc . l . file = stix - > c - > curinp - > name ;
2015-05-17 05:02:30 +00:00
stix - > c - > lxc = stix - > c - > curinp - > lxc ;
2015-05-19 15:16:18 +00:00
/* indicate that EOF has been read. lxc.c is also set to EOF. */
return 0 ;
2015-05-15 14:55:12 +00:00
}
2015-05-17 05:02:30 +00:00
stix - > c - > curinp - > b . pos = 0 ;
stix - > c - > curinp - > b . len = n ;
2015-05-15 14:55:12 +00:00
}
2016-09-06 16:06:22 +00:00
if ( stix - > c - > curinp - > lxc . c = = ' \n ' | | stix - > c - > curinp - > lxc . c = = ' \r ' )
2015-05-15 14:55:12 +00:00
{
2016-09-06 16:06:22 +00:00
/* stix->c->curinp->lxc.c is a previous character. the new character
* to be read is still in the buffer ( stix - > c - > curinp - > buf ) .
* stix - > cu - > curinp - > colm has been incremented when the previous
* character has been read . */
if ( stix - > c - > curinp - > line > 1 & &
stix - > c - > curinp - > colm = = 2 & &
stix - > c - > curinp - > nl ! = stix - > c - > curinp - > lxc . c )
{
/* most likely, it's the second character in '\r\n' or '\n\r'
* sequence . let ' s not update the line and column number . */
/*stix->c->curinp->colm = 1;*/
}
else
{
/* if the previous charater was a newline,
* increment the line counter and reset column to 1.
* incrementing the line number here instead of
* updating inp - > lxc causes the line number for
* TOK_EOF to be the same line as the lxc newline . */
stix - > c - > curinp - > line + + ;
stix - > c - > curinp - > colm = 1 ;
stix - > c - > curinp - > nl = stix - > c - > curinp - > lxc . c ;
}
2015-05-15 14:55:12 +00:00
}
2015-05-17 05:02:30 +00:00
2015-06-11 12:09:10 +00:00
lc = stix - > c - > curinp - > buf [ stix - > c - > curinp - > b . pos + + ] ;
if ( lc = = ' \n ' | | lc = = ' \r ' )
{
/* handle common newline conventions.
* LF + CR
* CR + LF
* LF
* CR
*/
if ( stix - > c - > curinp - > b . pos > = stix - > c - > curinp - > b . len )
{
n = stix - > c - > impl ( stix , STIX_IO_READ , stix - > c - > curinp ) ;
if ( n < = - 1 )
{
stix - > c - > curinp - > b . state = - 1 ;
goto done ;
}
else if ( n = = 0 )
{
stix - > c - > curinp - > b . state = 1 ;
goto done ;
}
else
{
stix - > c - > curinp - > b . pos = 0 ;
stix - > c - > curinp - > b . len = n ;
}
}
ec = ( lc = = ' \n ' ) ? ' \r ' : ' \n ' ;
if ( stix - > c - > curinp - > buf [ stix - > c - > curinp - > b . pos ] = = ec ) stix - > c - > curinp - > b . pos + + ;
done :
lc = STIX_UCI_NL ;
}
stix - > c - > curinp - > lxc . c = lc ;
2015-05-19 15:16:18 +00:00
stix - > c - > curinp - > lxc . l . line = stix - > c - > curinp - > line ;
stix - > c - > curinp - > lxc . l . colm = stix - > c - > curinp - > colm + + ;
stix - > c - > curinp - > lxc . l . file = stix - > c - > curinp - > name ;
2015-05-17 05:02:30 +00:00
stix - > c - > lxc = stix - > c - > curinp - > lxc ;
2015-05-19 15:16:18 +00:00
2015-05-17 05:02:30 +00:00
return 1 ; /* indicate that a normal character has been read */
2015-05-15 14:55:12 +00:00
}
2015-05-19 15:16:18 +00:00
static int skip_spaces ( stix_t * stix )
2015-05-15 14:55:12 +00:00
{
2015-07-10 14:06:07 +00:00
while ( is_spacechar ( stix - > c - > lxc . c ) ) GET_CHAR ( stix ) ;
2015-05-15 14:55:12 +00:00
return 0 ;
}
2015-05-19 15:16:18 +00:00
static int skip_comment ( stix_t * stix )
2015-05-15 14:55:12 +00:00
{
2015-10-28 14:58:58 +00:00
stix_ooci_t c = stix - > c - > lxc . c ;
2015-05-19 15:16:18 +00:00
stix_iolxc_t lc ;
if ( c = = ' " ' )
{
/* skip up to the closing " */
do
{
GET_CHAR_TO ( stix , c ) ;
if ( c = = STIX_UCI_EOF )
{
/* unterminated comment */
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_CMTNC , LEXER_LOC ( stix ) , STIX_NULL ) ;
2015-05-19 15:16:18 +00:00
return - 1 ;
}
}
while ( c ! = ' " ' ) ;
if ( c = = ' " ' ) GET_CHAR ( stix ) ;
return 1 ; /* double-quoted comment */
}
/* handle #! or ## */
if ( c ! = ' # ' ) return 0 ; /* not a comment */
/* save the last character */
lc = stix - > c - > lxc ;
/* read a new character */
GET_CHAR_TO ( stix , c ) ;
if ( c = = ' ! ' | | c = = ' # ' )
{
do
{
GET_CHAR_TO ( stix , c ) ;
if ( c = = STIX_UCI_EOF )
{
break ;
}
2016-09-06 16:06:22 +00:00
else if ( c = = ' \r ' | | c = = ' \n ' )
2015-05-19 15:16:18 +00:00
{
GET_CHAR ( stix ) ;
break ;
}
}
while ( 1 ) ;
return 1 ; /* single line comment led by ## or #! */
}
/* unget '#' */
unget_char ( stix , & stix - > c - > lxc ) ;
/* restore the previous state */
stix - > c - > lxc = lc ;
2015-05-15 14:55:12 +00:00
return 0 ;
}
2015-10-28 14:58:58 +00:00
static int get_ident ( stix_t * stix , stix_ooci_t char_read_ahead )
2015-05-15 14:55:12 +00:00
{
/*
2015-05-20 14:27:47 +00:00
* identifier : = alpha - char ( alpha - char | digit - char ) *
* keyword : = identifier " : "
2015-05-15 14:55:12 +00:00
*/
2015-10-28 14:58:58 +00:00
stix_ooci_t c ;
2015-06-23 14:00:26 +00:00
c = stix - > c - > lxc . c ;
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_IDENT ) ;
2015-05-15 14:55:12 +00:00
2015-06-24 11:53:19 +00:00
if ( char_read_ahead ! = STIX_UCI_EOF )
{
ADD_TOKEN_CHAR ( stix , char_read_ahead ) ;
}
2015-05-15 14:55:12 +00:00
do
{
2015-05-19 15:16:18 +00:00
ADD_TOKEN_CHAR ( stix , c ) ;
2015-06-23 14:00:26 +00:00
GET_CHAR_TO ( stix , c ) ;
2015-05-15 14:55:12 +00:00
}
2015-10-03 15:29:03 +00:00
while ( is_identchar ( c ) ) ;
2015-05-15 14:55:12 +00:00
2015-05-19 15:16:18 +00:00
if ( c = = ' : ' )
2015-05-15 14:55:12 +00:00
{
2015-07-10 14:06:07 +00:00
read_more_kwsym :
2015-05-19 15:16:18 +00:00
ADD_TOKEN_CHAR ( stix , c ) ;
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_KEYWORD ) ;
2015-06-23 14:00:26 +00:00
GET_CHAR_TO ( stix , c ) ;
2015-10-03 15:29:03 +00:00
if ( stix - > c - > in_array & & is_leadidentchar ( c ) )
2015-06-23 14:00:26 +00:00
{
2015-07-10 14:06:07 +00:00
/* when reading an array literal, read as many characters as
* would compose a normal keyword symbol literal */
do
{
ADD_TOKEN_CHAR ( stix , c ) ;
GET_CHAR_TO ( stix , c ) ;
}
2015-10-03 15:29:03 +00:00
while ( is_identchar ( c ) ) ;
2015-07-10 14:06:07 +00:00
if ( c = = ' : ' ) goto read_more_kwsym ;
else
{
/* the last character is not a colon */
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_COLON , LEXER_LOC ( stix ) , STIX_NULL ) ;
2015-07-10 14:06:07 +00:00
return - 1 ;
}
2015-06-23 14:00:26 +00:00
}
2015-05-15 14:55:12 +00:00
}
2015-05-21 17:07:55 +00:00
else
{
2015-07-10 14:06:07 +00:00
if ( c = = ' . ' )
{
stix_iolxc_t period ;
period = stix - > c - > lxc ;
read_more_seg :
GET_CHAR_TO ( stix , c ) ;
2015-10-03 15:29:03 +00:00
if ( is_leadidentchar ( c ) )
2015-07-10 14:06:07 +00:00
{
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_IDENT_DOTTED ) ;
2015-07-10 14:06:07 +00:00
ADD_TOKEN_CHAR ( stix , ' . ' ) ;
do
{
ADD_TOKEN_CHAR ( stix , c ) ;
GET_CHAR_TO ( stix , c ) ;
}
2015-10-03 15:29:03 +00:00
while ( is_identchar ( c ) ) ;
2015-07-10 14:06:07 +00:00
if ( c = = ' . ' ) goto read_more_seg ;
}
else
{
unget_char ( stix , & stix - > c - > lxc ) ;
stix - > c - > lxc = period ;
}
}
2015-05-21 17:07:55 +00:00
/* handle reserved words */
2015-07-13 15:35:52 +00:00
if ( is_token_word ( stix , VOCA_SELF ) )
2015-05-21 17:07:55 +00:00
{
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_SELF ) ;
2015-05-21 17:07:55 +00:00
}
2015-07-13 15:35:52 +00:00
else if ( is_token_word ( stix , VOCA_SUPER ) )
2015-05-21 17:07:55 +00:00
{
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_SUPER ) ;
2015-05-21 17:07:55 +00:00
}
2015-07-13 15:35:52 +00:00
else if ( is_token_word ( stix , VOCA_NIL ) )
2015-05-25 17:10:49 +00:00
{
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_NIL ) ;
2015-05-25 17:10:49 +00:00
}
2015-07-13 15:35:52 +00:00
else if ( is_token_word ( stix , VOCA_TRUE ) )
2015-05-21 17:07:55 +00:00
{
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_TRUE ) ;
2015-05-21 17:07:55 +00:00
}
2015-07-13 15:35:52 +00:00
else if ( is_token_word ( stix , VOCA_FALSE ) )
2015-05-21 17:07:55 +00:00
{
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_FALSE ) ;
2015-05-21 17:07:55 +00:00
}
2015-07-13 15:35:52 +00:00
else if ( is_token_word ( stix , VOCA_THIS_CONTEXT ) )
2015-05-21 17:07:55 +00:00
{
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_THIS_CONTEXT ) ;
2015-05-21 17:07:55 +00:00
}
2016-07-05 15:22:29 +00:00
else if ( is_token_word ( stix , VOCA_THIS_PROCESS ) )
{
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_THIS_PROCESS ) ;
2016-07-05 15:22:29 +00:00
}
2015-05-21 17:07:55 +00:00
}
2015-05-15 14:55:12 +00:00
return 0 ;
}
2015-05-19 15:16:18 +00:00
static int get_numlit ( stix_t * stix , int negated )
2015-05-15 14:55:12 +00:00
{
/*
2015-05-20 14:27:47 +00:00
* number - literal : = number | ( " - " number )
* number : = integer | float | scaledDecimal
* integer : = decimal - integer | radix - integer
* decimal - integer : = digit - char +
* radix - integer : = radix - specifier " r " radix - digit +
* radix - specifier : = digit - char +
* radix - digit : = digit - char | upper - alpha - char
*
* float : = mantissa [ exponentLetter exponent ]
* mantissa : = digit - char + " . " digit - char +
* exponent : = [ ' - ' ] decimal - integer
* exponentLetter : = ' e ' | ' d ' | ' q '
* scaledDecimal : = scaledMantissa ' s ' [ fractionalDigits ]
* scaledMantissa : = decimal - integer | mantissa
* fractionalDigits : = decimal - integer
2015-05-15 14:55:12 +00:00
*/
2015-10-28 14:58:58 +00:00
stix_ooci_t c ;
2015-06-16 13:29:29 +00:00
int radix = 0 , r ;
c = stix - > c - > lxc . c ;
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_NUMLIT ) ;
2015-05-15 14:55:12 +00:00
2015-05-20 14:27:47 +00:00
/*TODO: support a complex numeric literal */
2015-05-15 14:55:12 +00:00
do
{
2015-06-16 13:29:29 +00:00
if ( radix < = 36 )
{
/* collect the potential radix specifier */
r = CHAR_TO_NUM ( c , 10 ) ;
STIX_ASSERT ( r < 10 ) ;
radix = radix * 10 + r ;
}
2015-05-19 15:16:18 +00:00
ADD_TOKEN_CHAR ( stix , c ) ;
2015-06-16 13:29:29 +00:00
GET_CHAR_TO ( stix , c ) ;
2015-05-15 14:55:12 +00:00
}
2015-05-19 15:16:18 +00:00
while ( is_digitchar ( c ) ) ;
2015-05-15 14:55:12 +00:00
2015-06-16 13:29:29 +00:00
if ( c = = ' r ' )
{
/* radix specifier */
if ( radix < 2 | | radix > 36 )
{
/* no digit after the radix specifier */
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_RADIX , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-06-16 13:29:29 +00:00
return - 1 ;
}
ADD_TOKEN_CHAR ( stix , c ) ;
GET_CHAR_TO ( stix , c ) ;
if ( CHAR_TO_NUM ( c , radix ) > = radix )
{
/* no digit after the radix specifier */
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_RADNUMLIT , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-06-16 13:29:29 +00:00
return - 1 ;
}
do
{
ADD_TOKEN_CHAR ( stix , c ) ;
GET_CHAR_TO ( stix , c ) ;
}
while ( CHAR_TO_NUM ( c , radix ) < radix ) ;
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_RADNUMLIT ) ;
2015-06-16 13:29:29 +00:00
}
/*
* TODO : handle floating point number
*/
2015-05-15 14:55:12 +00:00
return 0 ;
}
2015-05-19 15:16:18 +00:00
static int get_charlit ( stix_t * stix )
2015-05-15 14:55:12 +00:00
{
/*
2015-05-20 14:27:47 +00:00
* character - literal : = " $ " character
* character : = normal - character | " ' "
2015-05-15 14:55:12 +00:00
*/
2015-10-28 14:58:58 +00:00
stix_ooci_t c = stix - > c - > lxc . c ; /* even a new-line or white space would be taken */
2015-05-19 15:16:18 +00:00
if ( c = = STIX_UCI_EOF )
2015-05-15 14:55:12 +00:00
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_CLTNT , LEXER_LOC ( stix ) , STIX_NULL ) ;
2015-05-15 14:55:12 +00:00
return - 1 ;
2015-05-19 15:16:18 +00:00
}
2015-05-15 14:55:12 +00:00
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_CHARLIT ) ;
2015-05-19 15:16:18 +00:00
ADD_TOKEN_CHAR ( stix , c ) ;
GET_CHAR ( stix ) ;
2015-05-15 14:55:12 +00:00
return 0 ;
}
2015-05-19 15:16:18 +00:00
static int get_strlit ( stix_t * stix )
2015-05-15 14:55:12 +00:00
{
/*
2015-05-20 14:27:47 +00:00
* string - literal : = single - quote string - character * single - quote
* string - character : = normal - character | ( single - quote single - quote )
* single - quote : = " ' "
* normal - character : = character - except - single - quote
2015-05-15 14:55:12 +00:00
*/
2015-10-28 14:58:58 +00:00
stix_ooci_t c = stix - > c - > lxc . c ;
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_STRLIT ) ;
2015-05-15 14:55:12 +00:00
do
{
do
{
2015-05-19 15:16:18 +00:00
ADD_TOKEN_CHAR ( stix , c ) ;
2015-05-20 14:27:47 +00:00
GET_CHAR_TO ( stix , c ) ;
2015-05-15 14:55:12 +00:00
2015-05-19 15:16:18 +00:00
if ( c = = STIX_UCI_EOF )
2015-05-15 14:55:12 +00:00
{
2015-05-19 15:16:18 +00:00
/* string not closed */
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_STRNC , TOKEN_LOC ( stix ) /*&stix->c->lxc.l*/ , STIX_NULL ) ;
2015-05-15 14:55:12 +00:00
return - 1 ;
}
}
2015-05-19 15:16:18 +00:00
while ( c ! = ' \' ' ) ;
2015-05-15 14:55:12 +00:00
2015-05-20 14:27:47 +00:00
GET_CHAR_TO ( stix , c ) ;
2015-05-15 14:55:12 +00:00
}
2015-05-19 15:16:18 +00:00
while ( c = = ' \' ' ) ;
2015-05-15 14:55:12 +00:00
return 0 ;
}
2015-12-17 16:11:10 +00:00
static int get_string ( stix_t * stix , stix_ooch_t end_char , stix_ooch_t esc_char , int regex , stix_oow_t preescaped )
2015-06-24 11:53:19 +00:00
{
2015-10-28 14:58:58 +00:00
stix_ooci_t c ;
2015-12-17 16:11:10 +00:00
stix_oow_t escaped = preescaped ;
stix_oow_t digit_count = 0 ;
2015-10-28 14:58:58 +00:00
stix_ooci_t c_acc = 0 ;
2015-06-24 11:53:19 +00:00
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_STRLIT ) ;
2015-06-24 11:53:19 +00:00
while ( 1 )
{
GET_CHAR_TO ( stix , c ) ;
if ( c = = STIX_UCI_EOF )
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_STRNC , TOKEN_LOC ( stix ) /*&stix->c->lxc.l*/ , STIX_NULL ) ;
2015-06-24 11:53:19 +00:00
return - 1 ;
}
if ( escaped = = 3 )
{
if ( c > = ' 0 ' & & c < = ' 7 ' )
{
c_acc = c_acc * 8 + c - ' 0 ' ;
digit_count + + ;
if ( digit_count > = escaped )
{
/* should i limit the max to 0xFF/0377?
* if ( c_acc > 0377 ) c_acc = 0377 ; */
ADD_TOKEN_CHAR ( stix , c_acc ) ;
escaped = 0 ;
}
continue ;
}
else
{
ADD_TOKEN_CHAR ( stix , c_acc ) ;
escaped = 0 ;
}
}
else if ( escaped = = 2 | | escaped = = 4 | | escaped = = 8 )
{
if ( c > = ' 0 ' & & c < = ' 9 ' )
{
c_acc = c_acc * 16 + c - ' 0 ' ;
digit_count + + ;
if ( digit_count > = escaped )
{
ADD_TOKEN_CHAR ( stix , c_acc ) ;
escaped = 0 ;
}
continue ;
}
else if ( c > = ' A ' & & c < = ' F ' )
{
c_acc = c_acc * 16 + c - ' A ' + 10 ;
digit_count + + ;
if ( digit_count > = escaped )
{
ADD_TOKEN_CHAR ( stix , c_acc ) ;
escaped = 0 ;
}
continue ;
}
else if ( c > = ' a ' & & c < = ' f ' )
{
c_acc = c_acc * 16 + c - ' a ' + 10 ;
digit_count + + ;
if ( digit_count > = escaped )
{
ADD_TOKEN_CHAR ( stix , c_acc ) ;
escaped = 0 ;
}
continue ;
}
else
{
2015-10-28 14:58:58 +00:00
stix_ooch_t rc ;
2015-06-24 11:53:19 +00:00
rc = ( escaped = = 2 ) ? ' x ' :
( escaped = = 4 ) ? ' u ' : ' U ' ;
if ( digit_count = = 0 )
ADD_TOKEN_CHAR ( stix , rc ) ;
else ADD_TOKEN_CHAR ( stix , c_acc ) ;
escaped = 0 ;
}
}
if ( escaped = = 0 & & c = = end_char )
{
/* terminating quote */
/*GET_CHAR_TO (stix, c);*/
GET_CHAR ( stix ) ;
break ;
}
if ( escaped = = 0 & & c = = esc_char )
{
escaped = 1 ;
continue ;
}
if ( escaped = = 1 )
{
if ( c = = ' n ' ) c = ' \n ' ;
else if ( c = = ' r ' ) c = ' \r ' ;
else if ( c = = ' t ' ) c = ' \t ' ;
else if ( c = = ' f ' ) c = ' \f ' ;
else if ( c = = ' b ' ) c = ' \b ' ;
else if ( c = = ' v ' ) c = ' \v ' ;
else if ( c = = ' a ' ) c = ' \a ' ;
else if ( c > = ' 0 ' & & c < = ' 7 ' & & ! regex )
{
/* i don't support the octal notation for a regular expression.
* it conflicts with the backreference notation between \ 1 and \ 7 inclusive . */
escaped = 3 ;
digit_count = 1 ;
c_acc = c - ' 0 ' ;
continue ;
}
else if ( c = = ' x ' )
{
escaped = 2 ;
digit_count = 0 ;
c_acc = 0 ;
continue ;
}
2015-10-28 14:58:58 +00:00
else if ( c = = ' u ' & & STIX_SIZEOF ( stix_ooch_t ) > = 2 )
2015-06-24 11:53:19 +00:00
{
escaped = 4 ;
digit_count = 0 ;
c_acc = 0 ;
continue ;
}
2015-10-28 14:58:58 +00:00
else if ( c = = ' U ' & & STIX_SIZEOF ( stix_ooch_t ) > = 4 )
2015-06-24 11:53:19 +00:00
{
escaped = 8 ;
digit_count = 0 ;
c_acc = 0 ;
continue ;
}
else if ( regex )
{
/* if the following character doesn't compose a proper
* escape sequence , keep the escape character .
* an unhandled escape sequence can be handled
* outside this function since the escape character
* is preserved . */
ADD_TOKEN_CHAR ( stix , esc_char ) ;
}
escaped = 0 ;
}
ADD_TOKEN_CHAR ( stix , c ) ;
}
return 0 ;
}
2015-05-19 15:16:18 +00:00
static int get_binsel ( stix_t * stix )
2015-05-15 14:55:12 +00:00
{
/*
2015-05-20 14:27:47 +00:00
* binary - selector : = binary - selector - character +
2015-05-15 14:55:12 +00:00
*/
2015-10-28 14:58:58 +00:00
stix_ooci_t oc ;
2015-05-15 14:55:12 +00:00
2015-05-19 15:16:18 +00:00
oc = stix - > c - > lxc . c ;
ADD_TOKEN_CHAR ( stix , oc ) ;
2015-05-15 14:55:12 +00:00
2015-05-19 15:16:18 +00:00
GET_CHAR ( stix ) ;
/* special case if a minus is followed by a digit immediately */
if ( oc = = ' - ' & & is_digitchar ( stix - > c - > lxc . c ) ) return get_numlit ( stix , 1 ) ;
2015-05-15 14:55:12 +00:00
/* up to 2 characters only */
2015-05-19 15:16:18 +00:00
if ( is_binselchar ( stix - > c - > lxc . c ) )
2015-05-15 14:55:12 +00:00
{
2015-05-19 15:16:18 +00:00
ADD_TOKEN_CHAR ( stix , stix - > c - > lxc . c ) ;
GET_CHAR ( stix ) ;
2015-05-15 14:55:12 +00:00
}
/* or up to any occurrences */
/*
2015-05-19 15:16:18 +00:00
while ( is_binselchar ( stix - > c - > lxc . c ) )
2015-05-15 14:55:12 +00:00
{
2015-05-19 15:16:18 +00:00
ADD_TOKEN_CHAR ( stix , c ) ;
GET_CHAR ( stix ) ;
2015-05-15 14:55:12 +00:00
}
*/
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_BINSEL ) ;
2015-05-15 14:55:12 +00:00
return 0 ;
}
2015-05-19 15:16:18 +00:00
static int get_token ( stix_t * stix )
2015-05-15 14:55:12 +00:00
{
2015-10-28 14:58:58 +00:00
stix_ooci_t c ;
2015-05-19 15:16:18 +00:00
int n ;
2015-05-15 14:55:12 +00:00
retry :
do
{
2015-05-19 15:16:18 +00:00
if ( skip_spaces ( stix ) < = - 1 ) return - 1 ;
if ( ( n = skip_comment ( stix ) ) < = - 1 ) return - 1 ;
2015-05-15 14:55:12 +00:00
}
2015-05-19 15:16:18 +00:00
while ( n > = 1 ) ;
2015-05-15 14:55:12 +00:00
2016-08-29 07:39:09 +00:00
/* clear the token name, reset its location */
SET_TOKEN_TYPE ( stix , STIX_IOTOK_EOF ) ; /* is it correct? */
CLEAR_TOKEN_NAME ( stix ) ;
2015-05-19 15:16:18 +00:00
stix - > c - > tok . loc = stix - > c - > lxc . l ;
c = stix - > c - > lxc . c ;
2015-05-15 14:55:12 +00:00
switch ( c )
{
2015-05-19 15:16:18 +00:00
case STIX_UCI_EOF :
2015-05-15 14:55:12 +00:00
{
int n ;
2015-05-19 15:16:18 +00:00
n = end_include ( stix ) ;
2015-05-15 14:55:12 +00:00
if ( n < = - 1 ) return - 1 ;
if ( n > = 1 ) goto retry ;
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_EOF ) ;
2015-06-03 17:24:11 +00:00
ADD_TOKEN_STR ( stix , vocas [ VOCA_EOF ] . str , vocas [ VOCA_EOF ] . len ) ;
2015-05-15 14:55:12 +00:00
break ;
}
2015-05-19 15:16:18 +00:00
case ' $ ' : /* character literal */
GET_CHAR ( stix ) ;
if ( get_charlit ( stix ) < = - 1 ) return - 1 ;
2015-05-15 14:55:12 +00:00
break ;
2015-05-19 15:16:18 +00:00
case ' \' ' : /* string literal */
GET_CHAR ( stix ) ;
if ( get_strlit ( stix ) < = - 1 ) return - 1 ;
2015-05-15 14:55:12 +00:00
break ;
2015-05-19 15:16:18 +00:00
case ' : ' :
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_COLON ) ;
2015-06-24 11:53:19 +00:00
ADD_TOKEN_CHAR ( stix , c ) ;
GET_CHAR_TO ( stix , c ) ;
2015-05-19 15:16:18 +00:00
if ( c = = ' = ' )
2015-05-15 14:55:12 +00:00
{
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_ASSIGN ) ;
2015-06-24 11:53:19 +00:00
ADD_TOKEN_CHAR ( stix , c ) ;
2015-05-19 15:16:18 +00:00
GET_CHAR ( stix ) ;
2015-05-15 14:55:12 +00:00
}
break ;
2015-05-19 15:16:18 +00:00
case ' ^ ' :
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_RETURN ) ;
2015-06-24 11:53:19 +00:00
ADD_TOKEN_CHAR ( stix , c ) ;
GET_CHAR_TO ( stix , c ) ;
#if 0
/* TODO: support explicit block return */
if ( c = = ' ^ ' )
{
/* ^^ */
2016-08-29 07:39:09 +00:00
TOKEN_TYPE ( stix ) = = STIX_IOTOK_BLKRET ;
2015-06-24 11:53:19 +00:00
ADD_TOKEN_CHAR ( stix , c ) ;
}
# endif
break ;
2015-05-19 15:16:18 +00:00
case ' { ' : /* extension */
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_LBRACE ) ;
2015-05-19 15:16:18 +00:00
goto single_char_token ;
case ' } ' : /* extension */
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_RBRACE ) ;
2015-05-19 15:16:18 +00:00
goto single_char_token ;
case ' [ ' :
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_LBRACK ) ;
2015-05-19 15:16:18 +00:00
goto single_char_token ;
case ' ] ' :
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_RBRACK ) ;
2015-05-19 15:16:18 +00:00
goto single_char_token ;
case ' ( ' :
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_LPAREN ) ;
2015-05-19 15:16:18 +00:00
goto single_char_token ;
case ' ) ' :
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_RPAREN ) ;
2015-05-19 15:16:18 +00:00
goto single_char_token ;
case ' . ' :
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_PERIOD ) ;
2015-05-19 15:16:18 +00:00
goto single_char_token ;
case ' ; ' :
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_SEMICOLON ) ;
2015-05-19 15:16:18 +00:00
goto single_char_token ;
case ' # ' :
2015-05-20 14:27:47 +00:00
/*
* The hash sign is not the part of the token name .
* ADD_TOKEN_CHAR ( stix , c ) ; */
2015-05-19 15:16:18 +00:00
GET_CHAR_TO ( stix , c ) ;
2015-05-15 14:55:12 +00:00
switch ( c )
{
2015-05-19 15:16:18 +00:00
case STIX_UCI_EOF :
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_HLTNT , LEXER_LOC ( stix ) , STIX_NULL ) ;
2015-05-15 14:55:12 +00:00
return - 1 ;
2015-05-19 15:16:18 +00:00
case ' ( ' :
2015-05-15 14:55:12 +00:00
/* #( */
2015-05-19 15:16:18 +00:00
ADD_TOKEN_CHAR ( stix , c ) ;
2016-09-06 16:06:22 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_ARPAREN ) ;
2015-05-19 15:16:18 +00:00
GET_CHAR ( stix ) ;
2015-05-15 14:55:12 +00:00
break ;
2015-05-20 14:27:47 +00:00
case ' [ ' :
/* #[ - byte array literal */
ADD_TOKEN_CHAR ( stix , c ) ;
2016-09-06 16:06:22 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_BAPAREN ) ;
2015-05-20 14:27:47 +00:00
GET_CHAR ( stix ) ;
break ;
2015-05-19 15:16:18 +00:00
case ' \' ' :
2015-05-20 14:27:47 +00:00
/* quoted symbol literal */
2015-05-19 15:16:18 +00:00
GET_CHAR ( stix ) ;
if ( get_strlit ( stix ) < = - 1 ) return - 1 ;
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_SYMLIT ) ;
2015-05-15 14:55:12 +00:00
break ;
default :
2015-05-20 14:27:47 +00:00
/* symbol-literal := "#" symbol-body
* symbol - body : = identifier | keyword + | binary - selector | string - literal
*/
2015-05-19 15:16:18 +00:00
2015-05-20 14:27:47 +00:00
/* unquoted symbol literal */
2015-05-19 15:16:18 +00:00
if ( is_binselchar ( c ) )
2015-05-15 14:55:12 +00:00
{
2015-05-19 15:16:18 +00:00
do
{
ADD_TOKEN_CHAR ( stix , c ) ;
GET_CHAR_TO ( stix , c ) ;
}
while ( is_binselchar ( c ) ) ;
2015-05-15 14:55:12 +00:00
}
2015-10-03 15:29:03 +00:00
else if ( is_leadidentchar ( c ) )
2015-05-19 15:16:18 +00:00
{
do
{
ADD_TOKEN_CHAR ( stix , c ) ;
GET_CHAR_TO ( stix , c ) ;
}
2015-10-03 15:29:03 +00:00
while ( is_identchar ( c ) ) ;
2015-05-19 15:16:18 +00:00
if ( c = = ' : ' )
{
2015-07-10 14:06:07 +00:00
/* keyword symbol - e.g. #ifTrue:ifFalse: */
read_more_word :
2015-05-19 15:16:18 +00:00
ADD_TOKEN_CHAR ( stix , c ) ;
GET_CHAR_TO ( stix , c ) ;
2015-10-03 15:29:03 +00:00
if ( is_leadidentchar ( c ) )
2015-05-19 16:26:52 +00:00
{
2015-07-10 14:06:07 +00:00
do
{
ADD_TOKEN_CHAR ( stix , c ) ;
GET_CHAR_TO ( stix , c ) ;
}
2015-10-03 15:29:03 +00:00
while ( is_identchar ( c ) ) ;
2015-07-10 14:06:07 +00:00
if ( c = = ' : ' ) goto read_more_word ;
else
{
/* if a colon is found in the middle of a symbol,
* the last charater is expected to be a colon as well .
* but , the last character is not a colon */
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_COLON , LEXER_LOC ( stix ) , STIX_NULL ) ;
2015-07-10 14:06:07 +00:00
return - 1 ;
}
2015-05-19 16:26:52 +00:00
}
}
2015-07-10 14:06:07 +00:00
else if ( c = = ' . ' )
2015-05-19 16:26:52 +00:00
{
2015-07-10 14:06:07 +00:00
/* dotted symbol e.g. #Planet.Earth.Object */
stix_iolxc_t period ;
period = stix - > c - > lxc ;
read_more_seg :
GET_CHAR_TO ( stix , c ) ;
2015-10-03 15:29:03 +00:00
if ( is_leadidentchar ( c ) )
2015-07-10 14:06:07 +00:00
{
ADD_TOKEN_CHAR ( stix , ' . ' ) ;
do
{
ADD_TOKEN_CHAR ( stix , c ) ;
GET_CHAR_TO ( stix , c ) ;
}
2015-10-03 15:29:03 +00:00
while ( is_identchar ( c ) ) ;
2015-07-10 14:06:07 +00:00
if ( c = = ' . ' ) goto read_more_seg ;
}
else
{
unget_char ( stix , & stix - > c - > lxc ) ;
stix - > c - > lxc = period ;
}
2015-05-19 15:16:18 +00:00
}
}
else
2015-05-15 14:55:12 +00:00
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_HLTNT , LEXER_LOC ( stix ) , STIX_NULL ) ;
2015-05-19 15:16:18 +00:00
return - 1 ;
}
2015-05-15 14:55:12 +00:00
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_SYMLIT ) ;
2015-05-15 14:55:12 +00:00
break ;
}
2015-06-24 11:53:19 +00:00
2015-05-15 14:55:12 +00:00
break ;
2015-06-24 11:53:19 +00:00
case ' C ' : /* a character with a C-style escape sequence */
case ' S ' : /* a string with a C-style escape sequences */
case ' M ' : /* a symbol with a C-style escape sequences */
{
2015-10-28 14:58:58 +00:00
stix_ooci_t saved_c = c ;
2015-06-24 11:53:19 +00:00
GET_CHAR_TO ( stix , c ) ;
if ( c = = ' \' ' )
{
/*GET_CHAR (stix);*/
if ( get_string ( stix , ' \' ' , ' \\ ' , 0 , 0 ) < = - 1 ) return - 1 ;
if ( saved_c = = ' C ' )
{
if ( stix - > c - > tok . name . len ! = 1 )
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_CHARLIT , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-06-24 11:53:19 +00:00
return - 1 ;
}
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_CHARLIT ) ;
2015-06-24 11:53:19 +00:00
}
else if ( saved_c = = ' M ' )
{
2016-08-29 07:39:09 +00:00
SET_TOKEN_TYPE ( stix , STIX_IOTOK_SYMLIT ) ;
2015-06-24 11:53:19 +00:00
}
}
else
{
if ( get_ident ( stix , saved_c ) < = - 1 ) return - 1 ;
}
break ;
}
/* case 'B': TODO: byte string with a c-style escape sequence? */
/* case 'R':
TODO : regular expression ?
GET_CHAR_TO ( stix , c ) ;
if ( c = = ' \' ' )
{
GET_CHAR ( stix ) ;
if ( get_rexlit ( stix ) < = - 1 ) return - 1 ;
}
else
{
if ( get_ident ( stix , ' R ' ) < = - 1 ) return - 1 ;
}
break ;
*/
2015-05-15 14:55:12 +00:00
default :
2015-10-03 15:29:03 +00:00
if ( is_leadidentchar ( c ) )
2015-05-15 14:55:12 +00:00
{
2015-06-24 11:53:19 +00:00
if ( get_ident ( stix , STIX_UCI_EOF ) < = - 1 ) return - 1 ;
2015-05-15 14:55:12 +00:00
}
2015-05-19 15:16:18 +00:00
else if ( is_digitchar ( c ) )
2015-05-15 14:55:12 +00:00
{
2015-06-24 11:53:19 +00:00
if ( get_numlit ( stix , 0 ) < = - 1 ) return - 1 ;
2015-05-15 14:55:12 +00:00
}
2015-05-19 15:16:18 +00:00
else if ( is_binselchar ( c ) )
2015-05-15 14:55:12 +00:00
{
/* binary selector */
2015-06-24 11:53:19 +00:00
if ( get_binsel ( stix ) < = - 1 ) return - 1 ;
2015-05-15 14:55:12 +00:00
}
else
{
2015-10-28 14:58:58 +00:00
stix - > c - > ilchr = ( stix_ooch_t ) c ;
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_ILCHR , LEXER_LOC ( stix ) , & stix - > c - > ilchr_ucs ) ;
2015-05-15 14:55:12 +00:00
return - 1 ;
}
break ;
2015-05-19 15:16:18 +00:00
single_char_token :
ADD_TOKEN_CHAR ( stix , c ) ;
GET_CHAR ( stix ) ;
break ;
2015-05-15 14:55:12 +00:00
}
2016-06-03 15:46:01 +00:00
/*stix_logbfmt (stix, STIX_FMTOUT_COMPILER | STIX_FMTOUT_DEBUG, "TOKEN: [%.*S]\n", stix->c->tok.name.len, stix->c->tok.name.ptr);*/
2015-05-15 14:55:12 +00:00
return 0 ;
}
2015-05-19 15:16:18 +00:00
static void clear_io_names ( stix_t * stix )
2015-05-15 14:55:12 +00:00
{
2015-05-19 15:16:18 +00:00
stix_iolink_t * cur ;
2015-06-12 13:52:30 +00:00
STIX_ASSERT ( stix - > c ! = STIX_NULL ) ;
2015-05-19 15:16:18 +00:00
while ( stix - > c - > io_names )
2015-05-15 14:55:12 +00:00
{
2015-05-19 15:16:18 +00:00
cur = stix - > c - > io_names ;
stix - > c - > io_names = cur - > link ;
stix_freemem ( stix , cur ) ;
2015-05-15 14:55:12 +00:00
}
}
2015-10-28 14:58:58 +00:00
static const stix_ooch_t * add_io_name ( stix_t * stix , const stix_oocs_t * name )
2015-05-15 14:55:12 +00:00
{
2015-05-19 15:16:18 +00:00
stix_iolink_t * link ;
2015-10-28 14:58:58 +00:00
stix_ooch_t * ptr ;
2015-05-15 14:55:12 +00:00
2015-10-28 14:58:58 +00:00
link = ( stix_iolink_t * ) stix_callocmem ( stix , STIX_SIZEOF ( * link ) + STIX_SIZEOF ( stix_ooch_t ) * ( name - > len + 1 ) ) ;
2015-05-19 15:16:18 +00:00
if ( ! link ) return STIX_NULL ;
2015-05-15 14:55:12 +00:00
2015-10-28 14:58:58 +00:00
ptr = ( stix_ooch_t * ) ( link + 1 ) ;
2015-05-21 17:07:55 +00:00
2015-10-28 14:58:58 +00:00
stix_copyoochars ( ptr , name - > ptr , name - > len ) ;
2015-05-21 17:07:55 +00:00
ptr [ name - > len ] = ' \0 ' ;
2015-05-19 15:16:18 +00:00
link - > link = stix - > c - > io_names ;
stix - > c - > io_names = link ;
2015-05-15 14:55:12 +00:00
2015-05-19 15:16:18 +00:00
return ptr ;
}
2015-05-15 14:55:12 +00:00
2015-05-19 15:16:18 +00:00
static int begin_include ( stix_t * stix )
{
2016-05-27 15:01:54 +00:00
stix_ioarg_t * arg ;
2015-10-28 14:58:58 +00:00
const stix_ooch_t * io_name ;
2015-05-19 15:16:18 +00:00
2016-08-29 07:39:09 +00:00
io_name = add_io_name ( stix , TOKEN_NAME ( stix ) ) ;
2015-05-20 14:27:47 +00:00
if ( ! io_name ) return - 1 ;
2015-05-19 15:16:18 +00:00
2016-05-27 15:01:54 +00:00
arg = ( stix_ioarg_t * ) stix_callocmem ( stix , STIX_SIZEOF ( * arg ) ) ;
2015-05-19 15:16:18 +00:00
if ( ! arg ) goto oops ;
arg - > name = io_name ;
2015-05-15 14:55:12 +00:00
arg - > line = 1 ;
arg - > colm = 1 ;
2016-09-06 16:06:22 +00:00
/*arg->nl = '\0';*/
2015-05-19 15:16:18 +00:00
arg - > includer = stix - > c - > curinp ;
2015-05-15 14:55:12 +00:00
2015-07-03 14:38:37 +00:00
if ( stix - > c - > impl ( stix , STIX_IO_OPEN , arg ) < = - 1 )
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_INCLUDE , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-07-03 14:38:37 +00:00
goto oops ;
}
2015-05-15 14:55:12 +00:00
2015-07-10 14:06:07 +00:00
GET_TOKEN ( stix ) ;
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) ! = STIX_IOTOK_PERIOD )
2015-07-10 14:06:07 +00:00
{
/* check if a period is following the includee name */
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_PERIOD , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-07-10 14:06:07 +00:00
goto oops ;
}
/* switch to theincludee's stream */
2015-05-19 15:16:18 +00:00
stix - > c - > curinp = arg ;
/* stix->c->depth.incl++; */
2015-05-15 14:55:12 +00:00
/* read in the first character in the included file.
* so the next call to get_token ( ) sees the character read
* from this file . */
2015-05-19 15:16:18 +00:00
if ( get_char ( stix ) < = - 1 | | get_token ( stix ) < = - 1 )
2015-05-15 14:55:12 +00:00
{
2015-05-19 15:16:18 +00:00
end_include ( stix ) ;
2015-05-15 14:55:12 +00:00
/* i don't jump to oops since i've called
2015-06-11 12:09:10 +00:00
* end_include ( ) which frees stix - > c - > curinp / arg */
2015-05-15 14:55:12 +00:00
return - 1 ;
}
return 0 ;
oops :
2015-05-19 15:16:18 +00:00
if ( arg ) stix_freemem ( stix , arg ) ;
2015-05-15 14:55:12 +00:00
return - 1 ;
}
2015-05-19 15:16:18 +00:00
static int end_include ( stix_t * stix )
2015-05-15 14:55:12 +00:00
{
int x ;
2016-05-27 15:01:54 +00:00
stix_ioarg_t * cur ;
2015-05-15 14:55:12 +00:00
2015-05-19 15:16:18 +00:00
if ( stix - > c - > curinp = = & stix - > c - > arg ) return 0 ; /* no include */
2015-05-15 14:55:12 +00:00
/* if it is an included file, close it and
* retry to read a character from an outer file */
2015-05-19 15:16:18 +00:00
x = stix - > c - > impl ( stix , STIX_IO_CLOSE , stix - > c - > curinp ) ;
2015-05-15 14:55:12 +00:00
/* if closing has failed, still destroy the
* sio structure first as normal and return
* the failure below . this way , the caller
2015-05-19 15:16:18 +00:00
* does not call STIX_IO_CLOSE on
* stix - > c - > curinp again . */
2015-05-15 14:55:12 +00:00
2015-05-19 15:16:18 +00:00
cur = stix - > c - > curinp ;
stix - > c - > curinp = stix - > c - > curinp - > includer ;
2015-05-15 14:55:12 +00:00
STIX_ASSERT ( cur - > name ! = STIX_NULL ) ;
2015-05-19 15:16:18 +00:00
stix_freemem ( stix , cur ) ;
/* stix->parse.depth.incl--; */
2015-05-15 14:55:12 +00:00
if ( x ! = 0 )
{
/* the failure mentioned above is returned here */
return - 1 ;
}
2015-05-19 15:16:18 +00:00
stix - > c - > lxc = stix - > c - > curinp - > lxc ;
2015-05-15 14:55:12 +00:00
return 1 ; /* ended the included file successfully */
}
2015-06-03 17:24:11 +00:00
/* ---------------------------------------------------------------------
* Byte - Code Generator
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2015-05-20 14:27:47 +00:00
2015-10-29 15:24:46 +00:00
static STIX_INLINE int emit_byte_instruction ( stix_t * stix , stix_oob_t code )
2015-05-15 14:55:12 +00:00
{
2015-12-17 16:11:10 +00:00
stix_oow_t i ;
2015-05-15 14:55:12 +00:00
2015-06-01 16:59:07 +00:00
i = stix - > c - > mth . code . len + 1 ;
2015-06-01 15:59:16 +00:00
if ( i > stix - > c - > mth . code_capa )
2015-05-15 14:55:12 +00:00
{
2015-10-29 15:24:46 +00:00
stix_oob_t * tmp ;
2015-06-01 15:59:16 +00:00
i = STIX_ALIGN ( i , CODE_BUFFER_ALIGN ) ;
2015-06-03 17:24:11 +00:00
tmp = stix_reallocmem ( stix , stix - > c - > mth . code . ptr , i * STIX_SIZEOF ( * tmp ) ) ;
2015-06-01 15:59:16 +00:00
if ( ! tmp ) return - 1 ;
stix - > c - > mth . code . ptr = tmp ;
stix - > c - > mth . code_capa = i ;
2015-05-15 14:55:12 +00:00
}
2015-06-01 16:59:07 +00:00
stix - > c - > mth . code . ptr [ stix - > c - > mth . code . len + + ] = code ;
return 0 ;
}
2015-06-29 13:52:40 +00:00
static int emit_single_param_instruction ( stix_t * stix , int cmd , stix_oow_t param_1 )
2015-06-01 16:59:07 +00:00
{
2015-10-29 15:24:46 +00:00
stix_oob_t bc ;
2015-06-01 16:59:07 +00:00
2015-06-29 13:52:40 +00:00
switch ( cmd )
2015-06-01 16:59:07 +00:00
{
2015-06-29 13:52:40 +00:00
case BCODE_PUSH_INSTVAR_0 :
case BCODE_STORE_INTO_INSTVAR_0 :
case BCODE_POP_INTO_INSTVAR_0 :
case BCODE_PUSH_TEMPVAR_0 :
case BCODE_STORE_INTO_TEMPVAR_0 :
case BCODE_POP_INTO_TEMPVAR_0 :
case BCODE_PUSH_LITERAL_0 :
if ( param_1 < 8 )
{
2015-12-27 10:19:36 +00:00
/* low 3 bits to hold the parameter */
2015-10-29 15:24:46 +00:00
bc = ( stix_oob_t ) ( cmd & 0xF8 ) | ( stix_oob_t ) param_1 ;
2015-06-29 13:52:40 +00:00
goto write_short ;
}
else
{
/* convert the code to a long version */
bc = cmd | 0x80 ;
goto write_long ;
}
case BCODE_PUSH_OBJECT_0 :
case BCODE_STORE_INTO_OBJECT_0 :
case BCODE_POP_INTO_OBJECT_0 :
case BCODE_JUMP_FORWARD_0 :
case BCODE_JUMP_BACKWARD_0 :
case BCODE_JUMP_IF_TRUE_0 :
case BCODE_JUMP_IF_FALSE_0 :
if ( param_1 < 4 )
{
2015-12-27 10:19:36 +00:00
/* low 2 bits to hold the parameter */
2015-10-29 15:24:46 +00:00
bc = ( stix_oob_t ) ( cmd & 0xFC ) | ( stix_oob_t ) param_1 ;
2015-06-29 13:52:40 +00:00
goto write_short ;
}
else
{
/* convert the code to a long version */
bc = cmd | 0x80 ;
goto write_long ;
}
2015-07-01 07:21:54 +00:00
case BCODE_JUMP2_FORWARD :
case BCODE_JUMP2_BACKWARD :
2015-07-02 15:45:48 +00:00
case BCODE_PUSH_INTLIT :
case BCODE_PUSH_NEGINTLIT :
2015-07-01 07:21:54 +00:00
bc = cmd ;
goto write_long ;
2015-06-01 16:59:07 +00:00
}
2015-06-01 15:59:16 +00:00
2015-06-29 13:52:40 +00:00
stix - > errnum = STIX_EINVAL ;
return - 1 ;
write_short :
if ( emit_byte_instruction ( stix , bc ) < = - 1 ) return - 1 ;
return 0 ;
write_long :
2015-06-30 14:47:39 +00:00
# if (STIX_BCODE_LONG_PARAM_SIZE == 2)
if ( emit_byte_instruction ( stix , bc ) < = - 1 | |
emit_byte_instruction ( stix , param_1 > > 8 ) < = - 1 | |
emit_byte_instruction ( stix , param_1 & 0xFF ) < = - 1 ) return - 1 ;
# else
if ( emit_byte_instruction ( stix , bc ) < = - 1 | |
emit_byte_instruction ( stix , param_1 ) < = - 1 ) return - 1 ;
# endif
2015-05-15 14:55:12 +00:00
return 0 ;
}
2015-12-17 16:11:10 +00:00
static int emit_double_param_instruction ( stix_t * stix , int cmd , stix_oow_t param_1 , stix_oow_t param_2 )
2015-06-29 13:52:40 +00:00
{
2015-10-29 15:24:46 +00:00
stix_oob_t bc ;
2015-05-15 14:55:12 +00:00
2015-06-29 13:52:40 +00:00
switch ( cmd )
2015-05-15 14:55:12 +00:00
{
2015-06-29 13:52:40 +00:00
case BCODE_STORE_INTO_CTXTEMPVAR_0 :
case BCODE_POP_INTO_CTXTEMPVAR_0 :
case BCODE_PUSH_CTXTEMPVAR_0 :
case BCODE_PUSH_OBJVAR_0 :
case BCODE_STORE_INTO_OBJVAR_0 :
case BCODE_POP_INTO_OBJVAR_0 :
case BCODE_SEND_MESSAGE_0 :
case BCODE_SEND_MESSAGE_TO_SUPER_0 :
2015-12-27 10:19:36 +00:00
if ( param_1 < 4 & & param_2 < 0xFF )
2015-06-29 13:52:40 +00:00
{
/* low 2 bits of the instruction code is the first parameter */
2015-10-29 15:24:46 +00:00
bc = ( stix_oob_t ) ( cmd & 0xFC ) | ( stix_oob_t ) param_1 ;
2015-06-29 13:52:40 +00:00
goto write_short ;
}
else
{
/* convert the code to a long version */
bc = cmd | 0x80 ;
goto write_long ;
}
2015-07-03 13:06:01 +00:00
case BCODE_MAKE_BLOCK :
bc = cmd ;
goto write_long ;
2015-05-15 14:55:12 +00:00
}
2015-06-29 13:52:40 +00:00
stix - > errnum = STIX_EINVAL ;
return - 1 ;
write_short :
if ( emit_byte_instruction ( stix , bc ) < = - 1 | |
emit_byte_instruction ( stix , param_2 ) < = - 1 ) return - 1 ;
return 0 ;
write_long :
2015-06-30 14:47:39 +00:00
# if (STIX_BCODE_LONG_PARAM_SIZE == 2)
if ( emit_byte_instruction ( stix , bc ) < = - 1 | |
emit_byte_instruction ( stix , param_1 > > 8 ) < = - 1 | |
emit_byte_instruction ( stix , param_1 & 0xFF ) < = - 1 | |
emit_byte_instruction ( stix , param_2 > > 8 ) < = - 1 | |
emit_byte_instruction ( stix , param_2 & 0xFF ) < = - 1 ) return - 1 ;
# else
if ( emit_byte_instruction ( stix , bc ) < = - 1 | |
emit_byte_instruction ( stix , param_1 ) < = - 1 | |
emit_byte_instruction ( stix , param_2 ) < = - 1 ) return - 1 ;
# endif
2015-06-03 17:24:11 +00:00
return 0 ;
2015-05-15 14:55:12 +00:00
}
2015-06-16 13:29:29 +00:00
static int emit_push_smint_literal ( stix_t * stix , stix_ooi_t i )
{
2015-12-17 16:11:10 +00:00
stix_oow_t index ;
2015-06-16 13:29:29 +00:00
switch ( i )
{
case - 1 :
2015-06-29 13:52:40 +00:00
return emit_byte_instruction ( stix , BCODE_PUSH_NEGONE ) ;
2015-06-16 13:29:29 +00:00
case 0 :
2015-06-29 13:52:40 +00:00
return emit_byte_instruction ( stix , BCODE_PUSH_ZERO ) ;
2015-06-16 13:29:29 +00:00
case 1 :
2015-06-29 13:52:40 +00:00
return emit_byte_instruction ( stix , BCODE_PUSH_ONE ) ;
case 2 :
return emit_byte_instruction ( stix , BCODE_PUSH_TWO ) ;
2015-06-16 13:29:29 +00:00
}
2015-07-02 15:45:48 +00:00
if ( i > = 0 & & i < = MAX_CODE_PARAM )
{
return emit_single_param_instruction ( stix , BCODE_PUSH_INTLIT , i ) ;
}
else if ( i < 0 & & i > = - ( stix_ooi_t ) MAX_CODE_PARAM )
{
return emit_single_param_instruction ( stix , BCODE_PUSH_NEGINTLIT , - i ) ;
}
2015-06-16 13:29:29 +00:00
2015-11-12 06:57:35 +00:00
if ( add_literal ( stix , STIX_SMOOI_TO_OOP ( i ) , & index ) < = - 1 | |
2015-06-29 13:52:40 +00:00
emit_single_param_instruction ( stix , BCODE_PUSH_LITERAL_0 , index ) < = - 1 ) return - 1 ;
2015-06-20 03:07:11 +00:00
2015-06-16 13:29:29 +00:00
return 0 ;
}
2015-06-03 17:24:11 +00:00
/* ---------------------------------------------------------------------
* Compiler
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2015-05-15 14:55:12 +00:00
2015-06-23 14:00:26 +00:00
2015-12-17 16:11:10 +00:00
static int add_literal ( stix_t * stix , stix_oop_t lit , stix_oow_t * index )
2015-05-15 14:55:12 +00:00
{
2015-12-17 16:11:10 +00:00
stix_oow_t i ;
2015-05-15 14:55:12 +00:00
2015-05-31 16:44:56 +00:00
for ( i = 0 ; i < stix - > c - > mth . literal_count ; i + + )
{
2015-05-15 14:55:12 +00:00
/*
2015-05-31 16:44:56 +00:00
* this removes redundancy of symbols , characters , and small integers .
* more complex redundacy check may be done somewhere else like
* in add_string_literal ( ) .
2015-05-15 14:55:12 +00:00
*/
2015-05-31 16:44:56 +00:00
if ( stix - > c - > mth . literals [ i ] = = lit )
{
* index = i ;
return i ;
}
2015-05-15 14:55:12 +00:00
}
2015-05-31 16:44:56 +00:00
if ( stix - > c - > mth . literal_count > = stix - > c - > mth . literal_capa )
{
stix_oop_t * tmp ;
2015-12-17 16:11:10 +00:00
stix_oow_t new_capa ;
2015-05-15 14:55:12 +00:00
2015-05-31 16:44:56 +00:00
new_capa = STIX_ALIGN ( stix - > c - > mth . literal_count + 1 , LITERAL_BUFFER_ALIGN ) ;
tmp = ( stix_oop_t * ) stix_reallocmem ( stix , stix - > c - > mth . literals , new_capa * STIX_SIZEOF ( * tmp ) ) ;
if ( ! tmp ) return - 1 ;
2015-05-15 14:55:12 +00:00
2015-05-31 16:44:56 +00:00
stix - > c - > mth . literal_capa = new_capa ;
stix - > c - > mth . literals = tmp ;
2015-05-15 14:55:12 +00:00
}
2015-05-31 16:44:56 +00:00
* index = stix - > c - > mth . literal_count ;
stix - > c - > mth . literals [ stix - > c - > mth . literal_count + + ] = lit ;
return 0 ;
2015-05-15 14:55:12 +00:00
}
2015-12-17 16:11:10 +00:00
static STIX_INLINE int add_character_literal ( stix_t * stix , stix_ooch_t ch , stix_oow_t * index )
2015-05-15 14:55:12 +00:00
{
2015-11-20 09:05:55 +00:00
return add_literal ( stix , STIX_CHAR_TO_OOP ( ch ) , index ) ;
2015-05-15 14:55:12 +00:00
}
2015-12-17 16:11:10 +00:00
static int add_string_literal ( stix_t * stix , const stix_oocs_t * str , stix_oow_t * index )
2015-05-15 14:55:12 +00:00
{
2015-05-31 16:44:56 +00:00
stix_oop_t lit ;
2015-12-17 16:11:10 +00:00
stix_oow_t i ;
2015-05-15 14:55:12 +00:00
2015-05-31 16:44:56 +00:00
for ( i = 0 ; i < stix - > c - > mth . literal_count ; i + + )
2015-05-15 14:55:12 +00:00
{
2015-05-31 16:44:56 +00:00
lit = stix - > c - > mth . literals [ i ] ;
if ( STIX_CLASSOF ( stix , lit ) = = stix - > _string & &
STIX_OBJ_GET_SIZE ( lit ) = = str - > len & &
stix_equalchars ( ( ( stix_oop_char_t ) lit ) - > slot , str - > ptr , str - > len ) )
{
* index = i ;
return 0 ;
}
2015-05-15 14:55:12 +00:00
}
2015-05-31 16:44:56 +00:00
lit = stix_instantiate ( stix , stix - > _string , str - > ptr , str - > len ) ;
if ( ! lit ) return - 1 ;
2015-05-15 14:55:12 +00:00
2015-05-31 16:44:56 +00:00
return add_literal ( stix , lit , index ) ;
}
2015-05-15 14:55:12 +00:00
2015-12-17 16:11:10 +00:00
static int add_symbol_literal ( stix_t * stix , const stix_oocs_t * str , stix_oow_t * index )
2015-05-31 16:44:56 +00:00
{
stix_oop_t tmp ;
2015-05-15 14:55:12 +00:00
2015-05-31 16:44:56 +00:00
tmp = stix_makesymbol ( stix , str - > ptr , str - > len ) ;
if ( ! tmp ) return - 1 ;
2015-05-15 14:55:12 +00:00
2015-06-03 17:24:11 +00:00
return add_literal ( stix , tmp , index ) ;
}
2015-05-15 14:55:12 +00:00
2015-10-28 14:58:58 +00:00
static STIX_INLINE int set_class_fqn ( stix_t * stix , const stix_oocs_t * name )
2015-05-25 17:10:49 +00:00
{
2015-07-13 15:35:52 +00:00
if ( copy_string_to ( stix , name , & stix - > c - > cls . fqn , & stix - > c - > cls . fqn_capa , 0 , ' \0 ' ) < = - 1 ) return - 1 ;
stix - > c - > cls . name = stix - > c - > cls . fqn ;
return 0 ;
2015-05-25 17:10:49 +00:00
}
2015-05-20 15:24:37 +00:00
2015-10-28 14:58:58 +00:00
static STIX_INLINE int set_superclass_fqn ( stix_t * stix , const stix_oocs_t * name )
2015-05-25 17:10:49 +00:00
{
2015-07-13 15:35:52 +00:00
if ( copy_string_to ( stix , name , & stix - > c - > cls . superfqn , & stix - > c - > cls . superfqn_capa , 0 , ' \0 ' ) < = - 1 ) return - 1 ;
stix - > c - > cls . supername = stix - > c - > cls . superfqn ;
return 0 ;
2015-05-25 17:10:49 +00:00
}
2015-05-20 15:24:37 +00:00
2015-10-28 14:58:58 +00:00
static STIX_INLINE int add_class_level_variable ( stix_t * stix , var_type_t index , const stix_oocs_t * name )
2015-05-25 17:10:49 +00:00
{
2015-05-26 16:31:47 +00:00
int n ;
2015-07-26 14:38:34 +00:00
n = copy_string_to ( stix , name , & stix - > c - > cls . vars [ index ] , & stix - > c - > cls . vars_capa [ index ] , 1 , ' ' ) ;
2015-05-26 16:31:47 +00:00
if ( n > = 0 )
{
2015-05-27 17:16:50 +00:00
stix - > c - > cls . var_count [ index ] + + ;
2015-05-28 15:20:27 +00:00
/* TODO: check if it exceeds STIX_MAX_NAMED_INSTVARS, STIX_MAX_CLASSVARS, STIX_MAX_CLASSINSTVARS */
2015-05-26 16:31:47 +00:00
}
return n ;
2015-05-25 17:10:49 +00:00
}
2015-10-28 14:58:58 +00:00
static STIX_INLINE int add_pool_dictionary ( stix_t * stix , const stix_oocs_t * name , stix_oop_set_t pooldic_oop )
2015-07-26 14:38:34 +00:00
{
2016-07-01 16:31:47 +00:00
if ( stix - > c - > cls . pooldic_count > = stix - > c - > cls . pooldic_oop_capa )
2015-07-26 14:38:34 +00:00
{
2016-07-01 16:31:47 +00:00
stix_oow_t new_capa ;
stix_oop_set_t * tmp ;
2015-07-26 14:38:34 +00:00
2016-07-01 16:31:47 +00:00
new_capa = STIX_ALIGN ( stix - > c - > cls . pooldic_oop_capa + 1 , POOLDIC_OOP_BUFFER_ALIGN ) ;
tmp = stix_reallocmem ( stix , stix - > c - > cls . pooldic_oops , new_capa * STIX_SIZEOF ( stix_oop_set_t ) ) ;
2016-08-29 06:10:02 +00:00
if ( ! tmp ) return - 1 ;
2015-07-26 14:38:34 +00:00
2016-07-01 16:31:47 +00:00
stix - > c - > cls . pooldic_oop_capa = new_capa ;
stix - > c - > cls . pooldic_oops = tmp ;
}
2015-07-26 14:38:34 +00:00
2016-07-01 16:31:47 +00:00
stix - > c - > cls . pooldic_oops [ stix - > c - > cls . pooldic_count ] = pooldic_oop ;
stix - > c - > cls . pooldic_count + + ;
2015-07-26 14:38:34 +00:00
/* TODO: check if pooldic_count overflows */
2016-07-01 16:31:47 +00:00
return 0 ;
2015-07-26 14:38:34 +00:00
}
2015-12-17 16:11:10 +00:00
static stix_ooi_t find_class_level_variable ( stix_t * stix , stix_oop_class_t self , const stix_oocs_t * name , var_info_t * var )
2015-05-25 17:10:49 +00:00
{
2015-12-17 16:11:10 +00:00
stix_oow_t pos ;
2015-05-25 17:10:49 +00:00
stix_oop_t super ;
stix_oop_char_t v ;
2015-05-27 17:16:50 +00:00
stix_oop_char_t * vv ;
2015-10-28 14:58:58 +00:00
stix_oocs_t hs ;
2015-05-27 17:16:50 +00:00
int index ;
if ( self )
{
STIX_ASSERT ( STIX_CLASSOF ( stix , self ) = = stix - > _class ) ;
2015-07-14 13:35:18 +00:00
/* [NOTE]
* the loop here assumes that the class has the following
* fields in the order shown below :
2015-05-27 17:16:50 +00:00
* instvars
* classvars
* classinstvars
*/
vv = & self - > instvars ;
for ( index = VAR_INSTANCE ; index < = VAR_CLASSINST ; index + + )
{
v = vv [ index ] ;
hs . ptr = v - > slot ;
hs . len = STIX_OBJ_GET_SIZE ( v ) ;
2015-05-25 17:10:49 +00:00
2015-07-15 02:36:24 +00:00
if ( find_word_in_string ( & hs , name , & pos ) > = 0 )
2015-05-27 17:16:50 +00:00
{
super = self - > superclass ;
2015-07-14 13:35:18 +00:00
/* 'self' may be STIX_NULL if STIX_NULL has been given for it.
* the caller must take good care when interpreting the meaning of
* this field */
var - > cls = self ;
2015-05-27 17:16:50 +00:00
goto done ;
}
}
super = self - > superclass ;
}
else
{
2015-07-14 13:35:18 +00:00
/* the class definition is not available yet.
* find the variable in the compiler ' s own list */
2015-05-27 17:16:50 +00:00
for ( index = VAR_INSTANCE ; index < = VAR_CLASSINST ; index + + )
{
2015-07-15 02:36:24 +00:00
if ( find_word_in_string ( & stix - > c - > cls . vars [ index ] , name , & pos ) > = 0 )
2015-05-27 17:16:50 +00:00
{
super = stix - > c - > cls . super_oop ;
2015-07-14 13:35:18 +00:00
var - > cls = self ;
2015-05-27 17:16:50 +00:00
goto done ;
}
}
super = stix - > c - > cls . super_oop ;
}
2015-05-25 18:13:52 +00:00
while ( super ! = stix - > _nil )
2015-05-25 17:10:49 +00:00
{
2015-05-25 18:13:52 +00:00
STIX_ASSERT ( STIX_CLASSOF ( stix , super ) = = stix - > _class ) ;
2015-05-25 17:10:49 +00:00
2015-07-14 13:35:18 +00:00
/* [NOTE]
* the loop here assumes that the class has the following
* fields in the order shown below :
2015-05-27 17:16:50 +00:00
* instvars
* classvars
* classinstvars
*/
vv = & ( ( stix_oop_class_t ) super ) - > instvars ;
for ( index = VAR_INSTANCE ; index < = VAR_CLASSINST ; index + + )
{
v = vv [ index ] ;
hs . ptr = v - > slot ;
hs . len = STIX_OBJ_GET_SIZE ( v ) ;
2015-07-15 02:36:24 +00:00
if ( find_word_in_string ( & hs , name , & pos ) > = 0 )
2015-05-27 17:16:50 +00:00
{
2015-07-14 13:35:18 +00:00
/* class variables reside in the class where the definition is found.
* that means a class variable is found in the definition of
* a superclass , the superclass is the placeholder of the
* class variable . on the other hand , instance variables and
* class instance variables live in the current class being
* compiled as they are inherited . */
var - > cls = ( index = = VAR_CLASS ) ? ( stix_oop_class_t ) super : self ;
2015-05-27 17:16:50 +00:00
super = ( ( stix_oop_class_t ) super ) - > superclass ;
goto done ;
}
}
2015-05-25 17:10:49 +00:00
2015-05-26 16:31:47 +00:00
super = ( ( stix_oop_class_t ) super ) - > superclass ;
2015-05-25 18:13:52 +00:00
}
2015-05-25 17:10:49 +00:00
2015-12-22 15:50:01 +00:00
stix - > errnum = STIX_ENOENT ;
2015-05-25 18:13:52 +00:00
return - 1 ;
2015-05-25 17:10:49 +00:00
2015-05-25 18:13:52 +00:00
done :
if ( super ! = stix - > _nil )
{
stix_oow_t spec ;
2015-07-14 13:35:18 +00:00
/* the class being compiled has a superclass */
2015-05-25 18:13:52 +00:00
STIX_ASSERT ( STIX_CLASSOF ( stix , super ) = = stix - > _class ) ;
2015-05-27 17:16:50 +00:00
switch ( index )
{
case VAR_INSTANCE :
/* each class has the number of named instance variables
* accumulated for inheritance . the position found in the
* local variable string can be adjusted by adding the
* number in the superclass */
2015-11-12 06:57:35 +00:00
spec = STIX_OOP_TO_SMOOI ( ( ( stix_oop_class_t ) super ) - > spec ) ;
2015-05-27 17:16:50 +00:00
pos + = STIX_CLASS_SPEC_NAMED_INSTVAR ( spec ) ;
break ;
case VAR_CLASS :
2015-07-14 13:35:18 +00:00
/* [NOTE]
* no adjustment is needed .
* a class object is composed of three parts .
* fixed - part | classinst - variables | class - variabes
* the position returned here doesn ' t consider
* class instance variables that can be potentially
* placed before the class variables . */
2015-05-27 17:16:50 +00:00
break ;
case VAR_CLASSINST :
2015-11-12 06:57:35 +00:00
spec = STIX_OOP_TO_SMOOI ( ( ( stix_oop_class_t ) super ) - > selfspec ) ;
2015-05-27 17:16:50 +00:00
pos + = STIX_CLASS_SELFSPEC_CLASSINSTVAR ( spec ) ;
break ;
}
2015-05-25 17:10:49 +00:00
}
2015-05-27 17:16:50 +00:00
var - > type = index ;
var - > pos = pos ;
2015-05-25 18:13:52 +00:00
return pos ;
2015-05-25 17:10:49 +00:00
}
2015-12-17 16:11:10 +00:00
static int clone_assignee ( stix_t * stix , const stix_oocs_t * name , stix_oow_t * offset )
2015-05-25 17:10:49 +00:00
{
2015-06-01 15:59:16 +00:00
int n ;
2015-12-17 16:11:10 +00:00
stix_oow_t old_len ;
2015-06-01 15:59:16 +00:00
old_len = stix - > c - > mth . assignees . len ;
n = copy_string_to ( stix , name , & stix - > c - > mth . assignees , & stix - > c - > mth . assignees_capa , 1 , ' \0 ' ) ;
if ( n < = - 1 ) return - 1 ;
/* update the pointer to of the name. its length is the same. */
2015-07-01 15:01:39 +00:00
/*name->ptr = stix->c->mth.assignees.ptr + old_len;*/
* offset = old_len ;
2015-06-01 15:59:16 +00:00
return 0 ;
}
2015-12-17 16:11:10 +00:00
static int clone_binary_selector ( stix_t * stix , const stix_oocs_t * name , stix_oow_t * offset )
2015-06-03 17:24:11 +00:00
{
int n ;
2015-12-17 16:11:10 +00:00
stix_oow_t old_len ;
2015-06-03 17:24:11 +00:00
old_len = stix - > c - > mth . binsels . len ;
n = copy_string_to ( stix , name , & stix - > c - > mth . binsels , & stix - > c - > mth . binsels_capa , 1 , ' \0 ' ) ;
if ( n < = - 1 ) return - 1 ;
/* update the pointer to of the name. its length is the same. */
2015-07-01 15:01:39 +00:00
/*name->ptr = stix->c->mth.binsels.ptr + old_len;*/
* offset = old_len ;
2015-06-03 17:24:11 +00:00
return 0 ;
}
2015-12-17 16:11:10 +00:00
static int clone_keyword ( stix_t * stix , const stix_oocs_t * name , stix_oow_t * offset )
2015-06-03 17:24:11 +00:00
{
int n ;
2015-12-17 16:11:10 +00:00
stix_oow_t old_len ;
2015-06-03 17:24:11 +00:00
old_len = stix - > c - > mth . kwsels . len ;
n = copy_string_to ( stix , name , & stix - > c - > mth . kwsels , & stix - > c - > mth . kwsels_capa , 1 , ' \0 ' ) ;
if ( n < = - 1 ) return - 1 ;
/* update the pointer to of the name. its length is the same. */
2015-07-01 15:01:39 +00:00
/*name->ptr = stix->c->mth.kwsels.ptr + old_len;*/
* offset = old_len ;
2015-06-03 17:24:11 +00:00
return 0 ;
}
2015-10-28 14:58:58 +00:00
static int add_method_name_fragment ( stix_t * stix , const stix_oocs_t * name )
2015-06-01 15:59:16 +00:00
{
/* method name fragments are concatenated without any delimiters */
2015-05-27 17:16:50 +00:00
return copy_string_to ( stix , name , & stix - > c - > mth . name , & stix - > c - > mth . name_capa , 1 , ' \0 ' ) ;
2015-05-25 17:10:49 +00:00
}
2015-10-28 14:58:58 +00:00
static int method_exists ( stix_t * stix , const stix_oocs_t * name )
2015-05-27 17:41:11 +00:00
{
2015-05-31 16:44:56 +00:00
/* check if the current class contains a method of the given name */
return stix_lookupdic ( stix , stix - > c - > cls . mthdic_oop [ stix - > c - > mth . type ] , name ) ! = STIX_NULL ;
2015-05-27 17:41:11 +00:00
}
2015-10-28 14:58:58 +00:00
static int add_temporary_variable ( stix_t * stix , const stix_oocs_t * name )
2015-05-25 17:10:49 +00:00
{
/* temporary variable names are added to the string with leading
* space if it ' s not the first variable */
2015-05-27 17:16:50 +00:00
return copy_string_to ( stix , name , & stix - > c - > mth . tmprs , & stix - > c - > mth . tmprs_capa , 1 , ' ' ) ;
2015-05-25 17:10:49 +00:00
}
2015-12-17 16:11:10 +00:00
static STIX_INLINE int find_temporary_variable ( stix_t * stix , const stix_oocs_t * name , stix_oow_t * xindex )
2015-05-25 17:10:49 +00:00
{
2015-07-15 02:36:24 +00:00
return find_word_in_string ( & stix - > c - > mth . tmprs , name , xindex ) ;
2015-05-25 17:10:49 +00:00
}
2015-10-28 14:58:58 +00:00
static stix_oop_set_t add_namespace ( stix_t * stix , stix_oop_set_t dic , const stix_oocs_t * name )
2015-07-13 15:58:27 +00:00
{
2015-12-17 16:11:10 +00:00
stix_oow_t tmp_count = 0 ;
2015-07-13 15:58:27 +00:00
stix_oop_t sym ;
stix_oop_set_t ns ;
stix_oop_association_t ass ;
stix_pushtmp ( stix , ( stix_oop_t * ) & dic ) ; tmp_count + + ;
sym = stix_makesymbol ( stix , name - > ptr , name - > len ) ;
if ( ! sym ) goto oops ;
stix_pushtmp ( stix , & sym ) ; tmp_count + + ;
ns = stix_makedic ( stix , stix - > _namespace , NAMESPACE_SIZE ) ;
if ( ! ns ) goto oops ;
/*stix_pushtmp (stix, &ns); tmp_count++;*/
ass = stix_putatdic ( stix , dic , sym , ( stix_oop_t ) ns ) ;
if ( ! ass ) goto oops ;
stix_poptmps ( stix , tmp_count ) ;
return ( stix_oop_set_t ) ass - > value ;
oops :
stix_poptmps ( stix , tmp_count ) ;
return STIX_NULL ;
}
2015-10-28 14:58:58 +00:00
static int preprocess_dotted_name ( stix_t * stix , int dont_add_ns , int accept_pooldic_as_ns , const stix_oocs_t * fqn , const stix_ioloc_t * fqn_loc , stix_oocs_t * name , stix_oop_set_t * ns_oop )
2015-07-13 15:58:27 +00:00
{
2015-10-28 14:58:58 +00:00
const stix_ooch_t * ptr , * dot ;
2015-12-17 16:11:10 +00:00
stix_oow_t len ;
2015-10-28 14:58:58 +00:00
stix_oocs_t seg ;
2015-07-13 15:58:27 +00:00
stix_oop_set_t dic ;
stix_oop_association_t ass ;
2015-07-15 08:39:18 +00:00
int pooldic_gotten = 0 ;
2015-07-13 15:58:27 +00:00
dic = stix - > sysdic ;
ptr = fqn - > ptr ;
len = fqn - > len ;
while ( 1 )
{
2015-10-28 14:58:58 +00:00
seg . ptr = ( stix_ooch_t * ) ptr ;
2015-07-13 15:58:27 +00:00
2015-10-28 14:58:58 +00:00
dot = stix_findoochar ( ptr , len , ' . ' ) ;
2015-07-13 15:58:27 +00:00
if ( dot )
{
2015-07-15 08:39:18 +00:00
if ( pooldic_gotten ) goto wrong_name ;
2015-07-13 15:58:27 +00:00
seg . len = dot - ptr ;
if ( is_reserved_word ( & seg ) ) goto wrong_name ;
ass = stix_lookupdic ( stix , dic , & seg ) ;
if ( ass )
{
if ( STIX_CLASSOF ( stix , ass - > value ) = = stix - > _namespace | |
2015-07-14 13:35:18 +00:00
( seg . ptr = = fqn - > ptr & & ass - > value = = ( stix_oop_t ) stix - > sysdic ) )
2015-07-13 15:58:27 +00:00
{
/* ok */
dic = ( stix_oop_set_t ) ass - > value ;
}
else
{
2015-07-15 08:39:18 +00:00
if ( accept_pooldic_as_ns & & STIX_CLASSOF ( stix , ass - > value ) = = stix - > _pool_dictionary )
{
/* A pool dictionary is treated as if it's a name space.
* However , the pool dictionary can only act as a name space
* if it ' s the second last segment . */
dic = ( stix_oop_set_t ) ass - > value ;
pooldic_gotten = 1 ;
}
else
{
goto wrong_name ;
}
2015-07-13 15:58:27 +00:00
}
}
else
{
stix_oop_set_t t ;
/* the segment does not exist. add it */
if ( dont_add_ns )
{
/* in '#extend Planet.Earth', it's an error
* if Planet doesn ' t exist */
goto wrong_name ;
}
/* When definining a new class, add a missing namespace */
t = add_namespace ( stix , dic , & seg ) ;
if ( ! t ) return - 1 ;
dic = t ;
}
}
else
{
/* this is the last segment. it should be a class name */
seg . len = len ;
if ( is_reserved_word ( & seg ) ) goto wrong_name ;
* name = seg ;
* ns_oop = dic ;
break ;
}
ptr = dot + 1 ;
len - = seg . len + 1 ;
}
return 0 ;
wrong_name :
seg . len + = seg . ptr - fqn - > ptr ;
seg . ptr = fqn - > ptr ;
set_syntax_error ( stix , STIX_SYNERR_NAMESPACE , fqn_loc , & seg ) ;
return - 1 ;
}
2016-07-01 16:31:47 +00:00
static int resolve_pooldic ( stix_t * stix , int dotted , const stix_oocs_t * name )
{
stix_oocs_t last ; /* the last segment */
stix_oop_set_t ns_oop ; /* name space */
stix_oop_association_t ass ;
stix_oow_t i ;
if ( dotted )
{
2016-08-29 07:39:09 +00:00
if ( preprocess_dotted_name ( stix , 0 , 0 , name , TOKEN_LOC ( stix ) , & last , & ns_oop ) < = - 1 ) return - 1 ;
2016-07-01 16:31:47 +00:00
}
else
{
last = * name ;
/* it falls back to the name space of the class */
ns_oop = stix - > c - > cls . ns_oop ;
}
/* check if the name refers to a pool dictionary */
ass = stix_lookupdic ( stix , ns_oop , & last ) ;
if ( ! ass | | STIX_CLASSOF ( stix , ass - > value ) ! = stix - > _pool_dictionary )
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_POOLDIC , TOKEN_LOC ( stix ) , name ) ;
2016-07-01 16:31:47 +00:00
return - 1 ;
}
/* check if the same dictionary pool has been declared for import */
for ( i = 0 ; i < stix - > c - > cls . pooldic_count ; i + + )
{
if ( ( stix_oop_set_t ) ass - > value = = stix - > c - > cls . pooldic_oops [ i ] )
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_POOLDICDUP , TOKEN_LOC ( stix ) , name ) ;
2016-07-01 16:31:47 +00:00
return - 1 ;
}
}
return 0 ;
}
2016-08-29 06:10:02 +00:00
static int import_pool_dictionary ( stix_t * stix , stix_oop_set_t ns_oop , const stix_oocs_t * tok_lastseg , const stix_oocs_t * tok_name , const stix_ioloc_t * tok_loc )
{
stix_oop_association_t ass ;
stix_oow_t i ;
/* check if the name refers to a pool dictionary */
ass = stix_lookupdic ( stix , ns_oop , tok_lastseg ) ;
if ( ! ass | | STIX_CLASSOF ( stix , ass - > value ) ! = stix - > _pool_dictionary )
{
set_syntax_error ( stix , STIX_SYNERR_POOLDIC , tok_loc , tok_name ) ;
return - 1 ;
}
/* check if the same dictionary pool has been declared for import */
for ( i = 0 ; i < stix - > c - > cls . pooldic_count ; i + + )
{
if ( ( stix_oop_set_t ) ass - > value = = stix - > c - > cls . pooldic_oops [ i ] )
{
set_syntax_error ( stix , STIX_SYNERR_POOLDICDUP , tok_loc , tok_name ) ;
return - 1 ;
}
}
if ( add_pool_dictionary ( stix , tok_name , ( stix_oop_set_t ) ass - > value ) < = - 1 ) return - 1 ;
if ( copy_string_to ( stix , tok_name , & stix - > c - > cls . pooldic , & stix - > c - > cls . pooldic_capa , 1 , ' ' ) < = - 1 )
{
stix - > c - > cls . pooldic_count - - ; /* roll back add_pool_dictionary() */
return - 1 ;
}
return 0 ;
}
2016-07-01 16:31:47 +00:00
2015-07-25 15:01:51 +00:00
static int compile_class_level_variables ( stix_t * stix )
{
var_type_t dcl_type = VAR_INSTANCE ;
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_LPAREN )
2015-07-25 15:01:51 +00:00
{
/* process variable modifiers */
GET_TOKEN ( stix ) ;
if ( is_token_symbol ( stix , VOCA_CLASS ) )
{
/* #dcl(#class) */
dcl_type = VAR_CLASS ;
GET_TOKEN ( stix ) ;
}
else if ( is_token_symbol ( stix , VOCA_CLASSINST ) )
{
/* #dcl(#classinst) */
dcl_type = VAR_CLASSINST ;
GET_TOKEN ( stix ) ;
}
else if ( is_token_symbol ( stix , VOCA_POOLDIC ) )
{
2016-07-01 16:31:47 +00:00
/* #dcl(#pooldic) - import a pool dictionary */
2015-07-25 15:01:51 +00:00
dcl_type = VAR_GLOBAL ; /* this is not a real type. use for branching below */
GET_TOKEN ( stix ) ;
}
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) ! = STIX_IOTOK_RPAREN )
2015-07-25 15:01:51 +00:00
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_RPAREN , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-07-25 15:01:51 +00:00
return - 1 ;
}
GET_TOKEN ( stix ) ;
}
if ( dcl_type = = VAR_GLOBAL )
{
2015-07-26 14:38:34 +00:00
/* pool dictionary import declaration
* # dcl ( # pooldic ) . . . */
2015-10-28 14:58:58 +00:00
stix_oocs_t last ;
2015-07-25 15:01:51 +00:00
stix_oop_set_t ns_oop ;
do
{
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_IDENT_DOTTED )
2015-07-25 15:01:51 +00:00
{
2016-08-29 07:39:09 +00:00
if ( preprocess_dotted_name ( stix , 0 , 0 , TOKEN_NAME ( stix ) , TOKEN_LOC ( stix ) , & last , & ns_oop ) < = - 1 ) return - 1 ;
2015-07-25 15:01:51 +00:00
}
2016-08-29 07:39:09 +00:00
else if ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_IDENT )
2015-07-25 15:01:51 +00:00
{
last = stix - > c - > tok . name ;
2015-07-26 14:38:34 +00:00
/* it falls back to the name space of the class */
ns_oop = stix - > c - > cls . ns_oop ;
2015-07-25 15:01:51 +00:00
}
else break ;
2016-08-29 07:39:09 +00:00
if ( import_pool_dictionary ( stix , ns_oop , & last , TOKEN_NAME ( stix ) , TOKEN_LOC ( stix ) ) < = - 1 ) return - 1 ;
2015-07-25 15:01:51 +00:00
GET_TOKEN ( stix ) ;
}
while ( 1 ) ;
}
else
{
2015-07-26 14:38:34 +00:00
/* variable declaration */
2015-07-25 15:01:51 +00:00
do
{
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_IDENT )
2015-07-25 15:01:51 +00:00
{
var_info_t var ;
2016-08-29 07:39:09 +00:00
if ( find_class_level_variable ( stix , STIX_NULL , TOKEN_NAME ( stix ) , & var ) > = 0 | |
stix_lookupdic ( stix , stix - > sysdic , TOKEN_NAME ( stix ) ) | | /* conflicts with a top global name */
stix_lookupdic ( stix , stix - > c - > cls . ns_oop , TOKEN_NAME ( stix ) ) ) /* conflicts with a global name in the class'es name space */
2015-07-25 15:01:51 +00:00
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_VARNAMEDUP , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-07-25 15:01:51 +00:00
return - 1 ;
}
2016-08-29 07:39:09 +00:00
if ( add_class_level_variable ( stix , dcl_type , TOKEN_NAME ( stix ) ) < = - 1 ) return - 1 ;
2015-07-25 15:01:51 +00:00
}
else
{
break ;
}
GET_TOKEN ( stix ) ;
}
while ( 1 ) ;
}
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) ! = STIX_IOTOK_PERIOD )
2015-07-25 15:01:51 +00:00
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_PERIOD , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-07-25 15:01:51 +00:00
return - 1 ;
}
GET_TOKEN ( stix ) ;
return 0 ;
}
2015-05-27 17:16:50 +00:00
static int compile_unary_method_name ( stix_t * stix )
2015-05-22 15:09:45 +00:00
{
2015-05-27 17:16:50 +00:00
STIX_ASSERT ( stix - > c - > mth . name . len = = 0 ) ;
STIX_ASSERT ( stix - > c - > mth . tmpr_nargs = = 0 ) ;
2015-05-22 15:09:45 +00:00
2016-08-29 07:39:09 +00:00
if ( add_method_name_fragment ( stix , TOKEN_NAME ( stix ) ) < = - 1 ) return - 1 ;
2015-05-22 15:09:45 +00:00
GET_TOKEN ( stix ) ;
return 0 ;
}
2015-05-27 17:16:50 +00:00
static int compile_binary_method_name ( stix_t * stix )
2015-05-22 15:09:45 +00:00
{
2015-05-27 17:16:50 +00:00
STIX_ASSERT ( stix - > c - > mth . name . len = = 0 ) ;
STIX_ASSERT ( stix - > c - > mth . tmpr_nargs = = 0 ) ;
2015-05-22 15:09:45 +00:00
2016-08-29 07:39:09 +00:00
if ( add_method_name_fragment ( stix , TOKEN_NAME ( stix ) ) < = - 1 ) return - 1 ;
2015-05-21 17:07:55 +00:00
GET_TOKEN ( stix ) ;
/* collect the argument name */
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) ! = STIX_IOTOK_IDENT )
2015-05-21 17:07:55 +00:00
{
/* wrong argument name. identifier expected */
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_IDENT , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-05-21 17:07:55 +00:00
return - 1 ;
}
2015-05-27 17:16:50 +00:00
STIX_ASSERT ( stix - > c - > mth . tmpr_nargs = = 0 ) ;
2015-05-21 17:07:55 +00:00
2015-05-27 17:41:11 +00:00
/* no duplication check is performed against class-level variable names.
* a duplcate name will shade a previsouly defined variable . */
2016-08-29 07:39:09 +00:00
if ( add_temporary_variable ( stix , TOKEN_NAME ( stix ) ) < = - 1 ) return - 1 ;
2015-05-27 17:16:50 +00:00
stix - > c - > mth . tmpr_nargs + + ;
2015-06-21 03:50:35 +00:00
STIX_ASSERT ( stix - > c - > mth . tmpr_nargs = = 1 ) ;
/* this check should not be not necessary
if ( stix - > c - > mth . tmpr_nargs > MAX_CODE_NARGS )
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_ARGFLOOD , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-06-21 03:50:35 +00:00
return - 1 ;
}
*/
2015-05-21 17:07:55 +00:00
GET_TOKEN ( stix ) ;
return 0 ;
}
2015-05-27 17:16:50 +00:00
static int compile_keyword_method_name ( stix_t * stix )
2015-05-21 17:07:55 +00:00
{
2015-05-27 17:16:50 +00:00
STIX_ASSERT ( stix - > c - > mth . name . len = = 0 ) ;
STIX_ASSERT ( stix - > c - > mth . tmpr_nargs = = 0 ) ;
2015-05-21 17:07:55 +00:00
do
{
2016-08-29 07:39:09 +00:00
if ( add_method_name_fragment ( stix , TOKEN_NAME ( stix ) ) < = - 1 ) return - 1 ;
2015-05-21 17:07:55 +00:00
GET_TOKEN ( stix ) ;
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) ! = STIX_IOTOK_IDENT )
2015-05-21 17:07:55 +00:00
{
2015-05-22 15:09:45 +00:00
/* wrong argument name. identifier is expected */
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_IDENT , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-05-21 17:07:55 +00:00
return - 1 ;
}
2016-08-29 07:39:09 +00:00
if ( find_temporary_variable ( stix , TOKEN_NAME ( stix ) , STIX_NULL ) > = 0 )
2015-05-21 17:07:55 +00:00
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_ARGNAMEDUP , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-05-21 17:07:55 +00:00
return - 1 ;
}
2016-08-29 07:39:09 +00:00
if ( add_temporary_variable ( stix , TOKEN_NAME ( stix ) ) < = - 1 ) return - 1 ;
2015-05-27 17:16:50 +00:00
stix - > c - > mth . tmpr_nargs + + ;
2015-05-21 17:07:55 +00:00
GET_TOKEN ( stix ) ;
}
2016-08-29 07:39:09 +00:00
while ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_KEYWORD ) ;
2015-05-21 17:07:55 +00:00
return 0 ;
}
2015-05-27 17:16:50 +00:00
static int compile_method_name ( stix_t * stix )
2015-05-21 17:07:55 +00:00
{
/*
2015-05-27 17:16:50 +00:00
* method - name : = unary - method - name | binary - method - name | keyword - method - name
* unary - method - name : = unary - selector
* binary - method - name : = binary - selector selector - argument
* keyword - method - name : = ( keyword selector - argument ) +
2015-05-21 17:07:55 +00:00
* selector - argument : = identifier
* unary - selector : = identifier
*/
int n ;
2015-05-27 17:16:50 +00:00
STIX_ASSERT ( stix - > c - > mth . tmpr_count = = 0 ) ;
2015-05-21 17:07:55 +00:00
2015-05-28 15:20:27 +00:00
stix - > c - > mth . name_loc = stix - > c - > tok . loc ;
2016-09-06 16:06:22 +00:00
switch ( TOKEN_TYPE ( stix ) )
2015-05-21 17:07:55 +00:00
{
case STIX_IOTOK_IDENT :
2015-05-27 17:16:50 +00:00
n = compile_unary_method_name ( stix ) ;
2015-05-21 17:07:55 +00:00
break ;
case STIX_IOTOK_BINSEL :
2015-05-27 17:16:50 +00:00
n = compile_binary_method_name ( stix ) ;
2015-05-21 17:07:55 +00:00
break ;
case STIX_IOTOK_KEYWORD :
2015-05-27 17:16:50 +00:00
n = compile_keyword_method_name ( stix ) ;
2015-05-21 17:07:55 +00:00
break ;
default :
2015-05-27 17:16:50 +00:00
/* illegal method name */
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_MTHNAME , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-05-21 17:07:55 +00:00
n = - 1 ;
}
2015-05-22 15:09:45 +00:00
if ( n > = 0 )
{
2015-05-31 16:44:56 +00:00
if ( method_exists ( stix , & stix - > c - > mth . name ) )
2015-05-27 17:41:11 +00:00
{
2015-05-28 15:20:27 +00:00
set_syntax_error ( stix , STIX_SYNERR_MTHNAMEDUP , & stix - > c - > mth . name_loc , & stix - > c - > mth . name ) ;
2015-05-27 17:41:11 +00:00
return - 1 ;
}
2015-05-22 15:09:45 +00:00
}
2015-06-21 03:50:35 +00:00
STIX_ASSERT ( stix - > c - > mth . tmpr_nargs < MAX_CODE_NARGS ) ;
2015-05-21 17:07:55 +00:00
/* the total number of temporaries is equal to the number of
* arguments after having processed the message pattern . it ' s because
* stix treats arguments the same as temporaries */
2015-05-27 17:16:50 +00:00
stix - > c - > mth . tmpr_count = stix - > c - > mth . tmpr_nargs ;
2015-05-21 17:07:55 +00:00
return n ;
}
2015-05-28 15:20:27 +00:00
static int compile_method_temporaries ( stix_t * stix )
2015-05-22 15:09:45 +00:00
{
/*
2015-05-27 17:16:50 +00:00
* method - temporaries : = " | " variable - list " | "
2015-05-22 15:09:45 +00:00
* variable - list : = identifier *
*/
2015-07-10 14:06:07 +00:00
if ( ! is_token_binary_selector ( stix , VOCA_VBAR ) )
2015-05-22 15:09:45 +00:00
{
/* return without doing anything if | is not found.
* this is not an error condition */
return 0 ;
}
GET_TOKEN ( stix ) ;
2016-08-29 07:39:09 +00:00
while ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_IDENT )
2015-05-22 15:09:45 +00:00
{
2016-08-29 07:39:09 +00:00
if ( find_temporary_variable ( stix , TOKEN_NAME ( stix ) , STIX_NULL ) > = 0 )
2015-05-22 15:09:45 +00:00
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_TMPRNAMEDUP , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-05-22 15:09:45 +00:00
return - 1 ;
}
2016-08-29 07:39:09 +00:00
if ( add_temporary_variable ( stix , TOKEN_NAME ( stix ) ) < = - 1 ) return - 1 ;
2015-05-27 17:16:50 +00:00
stix - > c - > mth . tmpr_count + + ;
2015-05-22 15:09:45 +00:00
2015-06-20 03:07:11 +00:00
if ( stix - > c - > mth . tmpr_count > MAX_CODE_NARGS )
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_TMPRFLOOD , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-06-20 03:07:11 +00:00
return - 1 ;
}
2015-05-22 15:09:45 +00:00
GET_TOKEN ( stix ) ;
}
2015-07-10 14:06:07 +00:00
if ( ! is_token_binary_selector ( stix , VOCA_VBAR ) )
2015-05-22 15:09:45 +00:00
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_VBAR , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-05-22 15:09:45 +00:00
return - 1 ;
}
GET_TOKEN ( stix ) ;
return 0 ;
}
2015-05-28 15:20:27 +00:00
static int compile_method_primitive ( stix_t * stix )
2015-05-22 15:09:45 +00:00
{
/*
2016-03-28 13:25:36 +00:00
* method - primitive : = " < " " primitive: " integer " > " |
* " < " " exception " " > "
2015-05-22 15:09:45 +00:00
*/
2015-07-02 15:45:48 +00:00
stix_ooi_t prim_no ;
2015-10-28 14:58:58 +00:00
const stix_ooch_t * ptr , * end ;
2015-05-22 15:09:45 +00:00
2015-07-10 14:06:07 +00:00
if ( ! is_token_binary_selector ( stix , VOCA_LT ) )
2015-05-22 15:09:45 +00:00
{
/* return if < is not seen. it is not an error condition */
return 0 ;
}
GET_TOKEN ( stix ) ;
2016-03-28 13:25:36 +00:00
if ( is_token_keyword ( stix , VOCA_PRIMITIVE_COLON ) )
2015-05-22 15:09:45 +00:00
{
2016-03-28 13:25:36 +00:00
GET_TOKEN ( stix ) ;
2016-09-06 16:06:22 +00:00
switch ( TOKEN_TYPE ( stix ) )
2016-03-28 13:25:36 +00:00
{
case STIX_IOTOK_NUMLIT : /* TODO: allow only an integer */
/*TODO: more checks the validity of the primitive number. support number with radix and so on support more extensive syntax. support primitive name, not number*/
ptr = stix - > c - > tok . name . ptr ;
end = ptr + stix - > c - > tok . name . len ;
prim_no = 0 ;
while ( ptr < end & & is_digitchar ( * ptr ) )
{
prim_no = prim_no * 10 + ( * ptr - ' 0 ' ) ;
2016-05-27 15:01:54 +00:00
if ( ! STIX_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE ( prim_no ) )
2016-03-28 13:25:36 +00:00
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_PRIMNO , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2016-03-28 13:25:36 +00:00
return - 1 ;
}
2015-10-08 14:26:04 +00:00
2016-03-28 13:25:36 +00:00
ptr + + ;
}
2015-05-22 15:09:45 +00:00
2016-03-28 13:25:36 +00:00
stix - > c - > mth . prim_no = prim_no ;
break ;
case STIX_IOTOK_SYMLIT :
2016-08-29 07:39:09 +00:00
prim_no = stix_getprimno ( stix , TOKEN_NAME ( stix ) ) ;
2016-03-28 13:25:36 +00:00
if ( prim_no < = - 1 )
2015-10-03 15:29:03 +00:00
{
2016-03-28 13:25:36 +00:00
const stix_ooch_t * us ;
/* the primitive is not found */
us = stix_findoochar ( stix - > c - > tok . name . ptr , stix - > c - > tok . name . len , ' _ ' ) ;
if ( us > stix - > c - > tok . name . ptr & & us < stix - > c - > tok . name . ptr + stix - > c - > tok . name . len - 1 )
{
stix_oow_t lit_idx ;
/* the symbol literal contains an underscore.
* and it is none of the first of the last character */
2016-08-29 07:39:09 +00:00
if ( add_symbol_literal ( stix , TOKEN_NAME ( stix ) , & lit_idx ) > = 0 & &
2016-05-27 15:01:54 +00:00
STIX_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE ( lit_idx ) )
2016-03-28 13:25:36 +00:00
{
stix - > c - > mth . prim_type = 2 ; /* named primitive */
stix - > c - > mth . prim_no = lit_idx ;
break ;
}
}
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_PRIMNO , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-10-03 15:29:03 +00:00
return - 1 ;
}
2016-05-27 15:01:54 +00:00
else if ( ! STIX_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE ( prim_no ) )
2015-10-08 14:26:04 +00:00
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_PRIMNO , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2016-03-28 13:25:36 +00:00
return - 1 ;
2015-10-08 14:26:04 +00:00
}
2016-03-28 13:25:36 +00:00
stix - > c - > mth . prim_type = 1 ;
stix - > c - > mth . prim_no = prim_no ;
break ;
2015-10-08 14:26:04 +00:00
2016-03-28 13:25:36 +00:00
default :
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_INTEGER , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2016-03-28 13:25:36 +00:00
return - 1 ;
}
2015-10-03 15:29:03 +00:00
2015-05-22 15:09:45 +00:00
}
2016-03-28 13:25:36 +00:00
else if ( is_token_word ( stix , VOCA_EXCEPTION ) )
{
/* TODO: exception handler is supposed to be used by BlockContext on:do:.
* it needs to check the number of arguments at least */
stix - > c - > mth . prim_type = 3 ;
}
2016-06-22 03:23:14 +00:00
else if ( is_token_word ( stix , VOCA_ENSURE ) )
{
stix - > c - > mth . prim_type = 4 ;
}
2016-03-28 13:25:36 +00:00
else
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_PRIMITIVE , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2016-03-28 13:25:36 +00:00
return - 1 ;
}
2015-05-22 15:09:45 +00:00
GET_TOKEN ( stix ) ;
2015-07-10 14:06:07 +00:00
if ( ! is_token_binary_selector ( stix , VOCA_GT ) )
2015-05-22 15:09:45 +00:00
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_GT , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-05-22 15:09:45 +00:00
return - 1 ;
}
GET_TOKEN ( stix ) ;
return 0 ;
}
2015-10-28 14:58:58 +00:00
static int get_variable_info ( stix_t * stix , const stix_oocs_t * name , const stix_ioloc_t * name_loc , int name_dotted , var_info_t * var )
2015-06-03 04:22:19 +00:00
{
2015-12-17 16:11:10 +00:00
stix_oow_t index ;
2015-06-11 12:09:10 +00:00
2015-06-03 17:24:11 +00:00
STIX_MEMSET ( var , 0 , STIX_SIZEOF ( * var ) ) ;
2015-06-01 15:59:16 +00:00
2015-07-10 14:06:07 +00:00
if ( name_dotted )
{
/* if a name is dotted,
*
* self . XXX - instance variable
* A . B . C - namespace or pool dictionary related reference .
*/
2015-07-13 15:58:27 +00:00
2015-10-28 14:58:58 +00:00
stix_oocs_t last ;
2015-07-13 15:58:27 +00:00
stix_oop_set_t ns_oop ;
stix_oop_association_t ass ;
2015-10-28 14:58:58 +00:00
const stix_ooch_t * dot ;
2015-07-26 14:38:34 +00:00
2015-10-28 14:58:58 +00:00
dot = stix_findoochar ( name - > ptr , name - > len , ' . ' ) ;
2015-07-26 14:38:34 +00:00
STIX_ASSERT ( dot ! = STIX_NULL ) ;
2015-12-03 15:11:47 +00:00
if ( dot - ( const stix_ooch_t * ) name - > ptr = = 4 & & stix_equalchars ( name - > ptr , vocas [ VOCA_SELF ] . str , 4 ) )
2015-07-26 14:38:34 +00:00
{
/* the dotted name begins with self. */
2015-10-28 14:58:58 +00:00
dot = stix_findoochar ( dot + 1 , name - > len - 5 , ' . ' ) ;
2015-07-26 14:38:34 +00:00
if ( ! dot )
{
/* the dotted name is composed of 2 segments only */
last . ptr = name - > ptr + 5 ;
last . len = name - > len - 5 ;
if ( ! is_reserved_word ( & last ) )
{
if ( find_class_level_variable ( stix , stix - > c - > cls . self_oop , & last , var ) > = 0 )
{
goto class_level_variable ;
}
else
{
/* undeclared identifier */
set_syntax_error ( stix , STIX_SYNERR_VARUNDCL , name_loc , name ) ;
return - 1 ;
}
}
}
}
2015-07-13 15:58:27 +00:00
2015-07-15 08:39:18 +00:00
if ( preprocess_dotted_name ( stix , 1 , 1 , name , name_loc , & last , & ns_oop ) < = - 1 ) return - 1 ;
2015-07-13 15:58:27 +00:00
ass = stix_lookupdic ( stix , ns_oop , & last ) ;
if ( ass )
{
var - > type = VAR_GLOBAL ;
var - > gbl = ass ;
}
else
{
/* undeclared identifier */
set_syntax_error ( stix , STIX_SYNERR_VARUNDCL , name_loc , name ) ;
return - 1 ;
}
return 0 ;
2015-07-10 14:06:07 +00:00
}
2015-07-15 02:36:24 +00:00
if ( find_temporary_variable ( stix , name , & index ) > = 0 )
2015-06-03 04:22:19 +00:00
{
2015-06-03 17:24:11 +00:00
var - > type = ( index < stix - > c - > mth . tmpr_nargs ) ? VAR_ARGUMENT : VAR_TEMPORARY ;
2015-06-03 04:22:19 +00:00
var - > pos = index ;
}
else
{
if ( find_class_level_variable ( stix , stix - > c - > cls . self_oop , name , var ) > = 0 )
{
2015-07-26 14:38:34 +00:00
class_level_variable :
2015-06-03 04:22:19 +00:00
switch ( var - > type )
{
case VAR_INSTANCE :
if ( stix - > c - > mth . type = = MTH_CLASS )
{
/* a class method cannot access an instance variable */
set_syntax_error ( stix , STIX_SYNERR_VARINACC , name_loc , name ) ;
return - 1 ;
}
break ;
2015-06-01 15:59:16 +00:00
2015-06-03 04:22:19 +00:00
case VAR_CLASS :
/* a class variable can be access by both instance methods and class methods */
STIX_ASSERT ( var - > cls ! = STIX_NULL ) ;
STIX_ASSERT ( STIX_CLASSOF ( stix , var - > cls ) = = stix - > _class ) ;
2015-06-01 15:59:16 +00:00
2015-07-14 13:35:18 +00:00
/* increment the position by the number of class instance variables
* as the class variables are placed after the class instance variables */
2015-06-03 17:24:11 +00:00
var - > pos + = STIX_CLASS_NAMED_INSTVARS +
2015-11-12 06:57:35 +00:00
STIX_CLASS_SELFSPEC_CLASSINSTVAR ( STIX_OOP_TO_SMOOI ( var - > cls - > selfspec ) ) ;
2015-06-03 04:22:19 +00:00
break ;
2015-06-01 15:59:16 +00:00
2015-06-03 04:22:19 +00:00
case VAR_CLASSINST :
/* class instance variable can be accessed by only class methods */
if ( stix - > c - > mth . type = = MTH_INSTANCE )
{
/* an instance method cannot access a class-instance variable */
set_syntax_error ( stix , STIX_SYNERR_VARINACC , name_loc , name ) ;
return - 1 ;
}
2015-06-01 15:59:16 +00:00
2015-06-03 04:22:19 +00:00
/* to a class object itself, a class-instance variable is
2015-06-03 17:24:11 +00:00
* just an instance variriable . but these are located
* after the named instance variables . */
var - > pos + = STIX_CLASS_NAMED_INSTVARS ;
2015-06-03 04:22:19 +00:00
break ;
2015-06-01 15:59:16 +00:00
2015-06-03 04:22:19 +00:00
default :
/* internal error - it must not happen */
stix - > errnum = STIX_EINTERN ;
return - 1 ;
}
}
2015-06-30 14:47:39 +00:00
else
2015-06-03 04:22:19 +00:00
{
2015-06-30 14:47:39 +00:00
stix_oop_association_t ass ;
2015-07-14 13:35:18 +00:00
/*ass = stix_lookupsysdic (stix, name);*/
ass = stix_lookupdic ( stix , stix - > c - > cls . ns_oop , name ) ;
if ( ! ass & & stix - > c - > cls . ns_oop ! = stix - > sysdic )
ass = stix_lookupdic ( stix , stix - > sysdic , name ) ;
2015-07-26 14:38:34 +00:00
2015-06-30 14:47:39 +00:00
if ( ass )
{
var - > type = VAR_GLOBAL ;
var - > gbl = ass ;
}
else
{
2015-12-17 16:11:10 +00:00
stix_oow_t i ;
2015-07-26 14:38:34 +00:00
stix_oop_association_t ass2 = STIX_NULL ;
/* attempt to find the variable in pool dictionaries */
for ( i = 0 ; i < stix - > c - > cls . pooldic_count ; i + + )
{
ass = stix_lookupdic ( stix , stix - > c - > cls . pooldic_oops [ i ] , name ) ;
if ( ass )
{
if ( ass2 )
{
/* the variable name has been found at least in 2 dictionaries */
set_syntax_error ( stix , STIX_SYNERR_VARAMBIG , name_loc , name ) ;
return - 1 ;
}
ass2 = ass ;
}
}
if ( ass2 )
{
var - > type = VAR_GLOBAL ;
var - > gbl = ass2 ;
}
else
{
/* undeclared identifier */
set_syntax_error ( stix , STIX_SYNERR_VARUNDCL , name_loc , name ) ;
return - 1 ;
}
2015-06-30 14:47:39 +00:00
}
2015-06-03 04:22:19 +00:00
}
}
2015-06-11 12:09:10 +00:00
if ( var - > pos > MAX_CODE_INDEX )
2015-06-01 15:59:16 +00:00
{
2015-06-03 04:22:19 +00:00
/* the assignee is not usable because its index is too large
* to be expressed in byte - codes . */
set_syntax_error ( stix , STIX_SYNERR_VARUNUSE , name_loc , name ) ;
return - 1 ;
2015-06-01 15:59:16 +00:00
}
2015-06-03 04:22:19 +00:00
2015-06-01 15:59:16 +00:00
return 0 ;
}
2015-06-03 17:24:11 +00:00
static int compile_block_temporaries ( stix_t * stix )
2015-05-25 17:10:49 +00:00
{
2015-06-03 17:24:11 +00:00
/*
* block - temporaries : = " | " variable - list " | "
* variable - list : = identifier *
2015-05-25 17:10:49 +00:00
*/
2015-07-10 14:06:07 +00:00
if ( ! is_token_binary_selector ( stix , VOCA_VBAR ) )
2015-06-03 17:24:11 +00:00
{
/* return without doing anything if | is not found.
* this is not an error condition */
return 0 ;
}
2015-06-01 15:59:16 +00:00
2015-06-03 17:24:11 +00:00
GET_TOKEN ( stix ) ;
2016-08-29 07:39:09 +00:00
while ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_IDENT )
2015-06-03 17:24:11 +00:00
{
2016-08-29 07:39:09 +00:00
if ( find_temporary_variable ( stix , TOKEN_NAME ( stix ) , STIX_NULL ) > = 0 )
2015-06-03 17:24:11 +00:00
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_TMPRNAMEDUP , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-06-03 17:24:11 +00:00
return - 1 ;
}
2016-08-29 07:39:09 +00:00
if ( add_temporary_variable ( stix , TOKEN_NAME ( stix ) ) < = - 1 ) return - 1 ;
2015-06-03 17:24:11 +00:00
stix - > c - > mth . tmpr_count + + ;
2015-06-20 03:07:11 +00:00
if ( stix - > c - > mth . tmpr_count > MAX_CODE_NTMPRS )
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_TMPRFLOOD , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-06-20 03:07:11 +00:00
return - 1 ;
}
2015-06-01 15:59:16 +00:00
2015-06-03 17:24:11 +00:00
GET_TOKEN ( stix ) ;
}
2015-06-03 04:22:19 +00:00
2015-07-10 14:06:07 +00:00
if ( ! is_token_binary_selector ( stix , VOCA_VBAR ) )
2015-05-25 17:10:49 +00:00
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_VBAR , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-06-03 17:24:11 +00:00
return - 1 ;
}
2015-06-01 15:59:16 +00:00
2015-06-03 17:24:11 +00:00
GET_TOKEN ( stix ) ;
return 0 ;
}
2015-06-03 04:22:19 +00:00
2015-12-17 16:11:10 +00:00
static int store_tmpr_count_for_block ( stix_t * stix , stix_oow_t tmpr_count )
2015-06-30 14:47:39 +00:00
{
if ( stix - > c - > mth . blk_depth > = stix - > c - > mth . blk_tmprcnt_capa )
{
2015-12-17 16:11:10 +00:00
stix_oow_t * tmp ;
stix_oow_t new_capa ;
2015-06-30 14:47:39 +00:00
new_capa = STIX_ALIGN ( stix - > c - > mth . blk_depth + 1 , BLK_TMPRCNT_BUFFER_ALIGN ) ;
2015-12-17 16:11:10 +00:00
tmp = ( stix_oow_t * ) stix_reallocmem ( stix , stix - > c - > mth . blk_tmprcnt , new_capa * STIX_SIZEOF ( * tmp ) ) ;
2015-06-30 14:47:39 +00:00
if ( ! tmp ) return - 1 ;
stix - > c - > mth . blk_tmprcnt_capa = new_capa ;
stix - > c - > mth . blk_tmprcnt = tmp ;
}
2016-01-29 04:04:39 +00:00
/* [NOTE] i don't increment blk_depth here. it's updated
* by the caller after this function has been called for
* a new block entered . */
2015-06-30 14:47:39 +00:00
stix - > c - > mth . blk_tmprcnt [ stix - > c - > mth . blk_depth ] = tmpr_count ;
return 0 ;
}
2015-06-03 17:24:11 +00:00
static int compile_block_expression ( stix_t * stix )
{
2015-12-17 16:11:10 +00:00
stix_oow_t jump_inst_pos ;
stix_oow_t saved_tmpr_count , saved_tmprs_len ;
stix_oow_t block_arg_count , block_tmpr_count ;
stix_oow_t block_code_size ;
2015-06-20 03:07:11 +00:00
stix_ioloc_t block_loc , colon_loc , tmpr_loc ;
2015-06-16 04:31:28 +00:00
2015-06-03 17:24:11 +00:00
/*
* block - expression : = " [ " block - body " ] "
* block - body : = ( block - argument * " | " ) ? block - temporaries ? method - statement *
* block - argument : = " : " identifier
*/
2015-06-03 04:22:19 +00:00
2015-06-16 13:29:29 +00:00
/* this function expects [ not to be consumed away */
2016-08-29 07:39:09 +00:00
STIX_ASSERT ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_LBRACK ) ;
2015-06-16 13:29:29 +00:00
block_loc = stix - > c - > tok . loc ;
GET_TOKEN ( stix ) ;
2015-06-16 04:31:28 +00:00
2015-06-17 13:46:16 +00:00
saved_tmprs_len = stix - > c - > mth . tmprs . len ;
2015-06-16 13:29:29 +00:00
saved_tmpr_count = stix - > c - > mth . tmpr_count ;
2015-06-30 14:47:39 +00:00
STIX_ASSERT ( stix - > c - > mth . blk_depth > 0 ) ;
STIX_ASSERT ( stix - > c - > mth . blk_tmprcnt [ stix - > c - > mth . blk_depth - 1 ] = = saved_tmpr_count ) ;
2015-06-16 04:31:28 +00:00
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_COLON )
2015-06-03 17:24:11 +00:00
{
2015-06-16 13:29:29 +00:00
colon_loc = stix - > c - > tok . loc ;
2015-06-03 17:24:11 +00:00
/* block temporary variables */
do
{
GET_TOKEN ( stix ) ;
2015-06-03 04:22:19 +00:00
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) ! = STIX_IOTOK_IDENT )
2015-06-03 17:24:11 +00:00
{
/* wrong argument name. identifier expected */
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_IDENT , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-06-03 17:24:11 +00:00
return - 1 ;
}
2015-06-01 15:59:16 +00:00
2015-06-03 17:24:11 +00:00
/* TODO: check conflicting names as well */
2016-08-29 07:39:09 +00:00
if ( find_temporary_variable ( stix , TOKEN_NAME ( stix ) , STIX_NULL ) > = 0 )
2015-06-16 13:29:29 +00:00
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_BLKARGNAMEDUP , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-06-16 13:29:29 +00:00
return - 1 ;
}
2016-08-29 07:39:09 +00:00
if ( add_temporary_variable ( stix , TOKEN_NAME ( stix ) ) < = - 1 ) return - 1 ;
2015-06-17 13:46:16 +00:00
stix - > c - > mth . tmpr_count + + ;
2015-06-20 03:07:11 +00:00
if ( stix - > c - > mth . tmpr_count > MAX_CODE_NARGS )
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_BLKARGFLOOD , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-06-20 03:07:11 +00:00
return - 1 ;
}
2015-06-16 13:29:29 +00:00
2015-06-03 17:24:11 +00:00
GET_TOKEN ( stix ) ;
}
2016-08-29 07:39:09 +00:00
while ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_COLON ) ;
2015-06-03 04:22:19 +00:00
2015-07-10 14:06:07 +00:00
if ( ! is_token_binary_selector ( stix , VOCA_VBAR ) )
2015-06-03 17:24:11 +00:00
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_VBAR , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-06-03 04:22:19 +00:00
return - 1 ;
2015-06-03 17:24:11 +00:00
}
GET_TOKEN ( stix ) ;
2015-06-01 15:59:16 +00:00
}
2015-06-03 04:22:19 +00:00
2015-06-16 13:29:29 +00:00
block_arg_count = stix - > c - > mth . tmpr_count - saved_tmpr_count ;
if ( block_arg_count > MAX_CODE_NBLKARGS )
{
2015-06-17 13:46:16 +00:00
/* while an integer object is pused to indicate the number of
* block arguments , evaluation which is done by message passing
* limits the number of arguments that can be passed . so the
* check is implemented */
2015-06-16 13:29:29 +00:00
set_syntax_error ( stix , STIX_SYNERR_BLKARGFLOOD , & colon_loc , STIX_NULL ) ;
return - 1 ;
}
2015-06-20 03:07:11 +00:00
tmpr_loc = stix - > c - > tok . loc ;
if ( compile_block_temporaries ( stix ) < = - 1 ) return - 1 ;
2015-06-30 14:47:39 +00:00
/* this is a block-local temporary count including arguments */
2015-06-20 03:07:11 +00:00
block_tmpr_count = stix - > c - > mth . tmpr_count - saved_tmpr_count ;
if ( block_tmpr_count > MAX_CODE_NBLKTMPRS )
{
set_syntax_error ( stix , STIX_SYNERR_BLKTMPRFLOOD , & tmpr_loc , STIX_NULL ) ;
return - 1 ;
}
2016-01-29 04:04:39 +00:00
/* store the accumulated number of temporaries for the current block.
* block depth is not rasised as it ' s not entering a new block but
* updating the temporaries count for the current block . */
2015-06-30 14:47:39 +00:00
if ( store_tmpr_count_for_block ( stix , stix - > c - > mth . tmpr_count ) < = - 1 ) return - 1 ;
2015-07-03 13:06:01 +00:00
# if defined(STIX_USE_MAKE_BLOCK)
if ( emit_double_param_instruction ( stix , BCODE_MAKE_BLOCK , block_arg_count , stix - > c - > mth . tmpr_count /*block_tmpr_count*/ ) < = - 1 ) return - 1 ;
# else
2015-06-29 13:52:40 +00:00
if ( emit_byte_instruction ( stix , BCODE_PUSH_CONTEXT ) < = - 1 | |
2015-06-16 13:29:29 +00:00
emit_push_smint_literal ( stix , block_arg_count ) < = - 1 | |
2015-06-22 14:21:46 +00:00
emit_push_smint_literal ( stix , stix - > c - > mth . tmpr_count /*block_tmpr_count*/ ) < = - 1 | |
2015-06-29 13:52:40 +00:00
emit_byte_instruction ( stix , BCODE_SEND_BLOCK_COPY ) < = - 1 ) return - 1 ;
2015-07-03 13:06:01 +00:00
# endif
2015-06-16 13:29:29 +00:00
/* insert dummy instructions before replacing them with a jump instruction */
jump_inst_pos = stix - > c - > mth . code . len ;
2015-06-30 14:47:39 +00:00
/* specifying MAX_CODE_JUMP causes emit_single_param_instruction() to
* produce the long jump instruction ( BCODE_JUMP_FORWARD_X ) */
if ( emit_single_param_instruction ( stix , BCODE_JUMP_FORWARD_0 , MAX_CODE_JUMP ) < = - 1 ) return - 1 ;
2015-06-16 13:29:29 +00:00
2015-06-20 03:07:11 +00:00
/* compile statements inside a block */
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_RBRACK )
2015-06-03 17:24:11 +00:00
{
2015-06-20 03:07:11 +00:00
/* the block is empty */
2015-06-29 13:52:40 +00:00
if ( emit_byte_instruction ( stix , BCODE_PUSH_NIL ) < = - 1 ) return - 1 ;
2015-06-20 03:07:11 +00:00
}
else
{
2016-08-29 07:39:09 +00:00
while ( TOKEN_TYPE ( stix ) ! = STIX_IOTOK_EOF )
2015-06-20 03:07:11 +00:00
{
if ( compile_block_statement ( stix ) < = - 1 ) return - 1 ;
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_RBRACK ) break ;
else if ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_PERIOD )
2015-06-20 03:07:11 +00:00
{
GET_TOKEN ( stix ) ;
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_RBRACK ) break ;
2015-06-29 13:52:40 +00:00
if ( emit_byte_instruction ( stix , BCODE_POP_STACKTOP ) < = - 1 ) return - 1 ;
2015-06-20 03:07:11 +00:00
}
else
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_RBRACK , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-06-20 03:07:11 +00:00
return - 1 ;
}
}
2015-06-03 17:24:11 +00:00
}
2016-02-12 16:23:26 +00:00
if ( emit_byte_instruction ( stix , BCODE_RETURN_FROM_BLOCK ) < = - 1 ) return - 1 ;
2015-06-29 13:52:40 +00:00
block_code_size = stix - > c - > mth . code . len - jump_inst_pos - ( STIX_BCODE_LONG_PARAM_SIZE + 1 ) ;
2015-07-01 07:21:54 +00:00
if ( block_code_size > MAX_CODE_JUMP * 2 )
2015-06-16 13:29:29 +00:00
{
2015-06-17 13:46:16 +00:00
set_syntax_error ( stix , STIX_SYNERR_BLKFLOOD , & block_loc , STIX_NULL ) ;
2015-06-16 13:29:29 +00:00
return - 1 ;
}
2015-07-01 07:21:54 +00:00
else
{
2015-12-17 16:11:10 +00:00
stix_oow_t jump_offset ;
2015-06-03 17:24:11 +00:00
2015-07-01 07:21:54 +00:00
if ( block_code_size > MAX_CODE_JUMP )
{
stix - > c - > mth . code . ptr [ jump_inst_pos ] = BCODE_JUMP2_FORWARD ;
jump_offset = block_code_size - MAX_CODE_JUMP ;
}
else
{
jump_offset = block_code_size ;
}
# if (STIX_BCODE_LONG_PARAM_SIZE == 2)
stix - > c - > mth . code . ptr [ jump_inst_pos + 1 ] = jump_offset > > 8 ;
stix - > c - > mth . code . ptr [ jump_inst_pos + 2 ] = jump_offset & 0xFF ;
# else
stix - > c - > mth . code . ptr [ jump_inst_pos + 1 ] = jump_offset ;
# endif
}
2015-06-17 13:46:16 +00:00
/* restore the temporary count */
stix - > c - > mth . tmprs . len = saved_tmprs_len ;
2015-06-30 14:47:39 +00:00
stix - > c - > mth . tmpr_count = saved_tmpr_count ;
2015-06-16 13:29:29 +00:00
GET_TOKEN ( stix ) ;
2015-06-03 17:24:11 +00:00
return 0 ;
}
2015-06-03 04:22:19 +00:00
2016-01-29 04:04:39 +00:00
static int add_to_byte_array_literal_buffer ( stix_t * stix , stix_oob_t b )
2015-06-23 14:00:26 +00:00
{
if ( stix - > c - > mth . balit_count > = stix - > c - > mth . balit_capa )
{
2015-10-29 15:24:46 +00:00
stix_oob_t * tmp ;
2015-12-17 16:11:10 +00:00
stix_oow_t new_capa ;
2015-06-23 14:00:26 +00:00
new_capa = STIX_ALIGN ( stix - > c - > mth . balit_count + 1 , BALIT_BUFFER_ALIGN ) ;
2015-10-29 15:24:46 +00:00
tmp = ( stix_oob_t * ) stix_reallocmem ( stix , stix - > c - > mth . balit , new_capa * STIX_SIZEOF ( * tmp ) ) ;
2015-06-23 14:00:26 +00:00
if ( ! tmp ) return - 1 ;
stix - > c - > mth . balit_capa = new_capa ;
stix - > c - > mth . balit = tmp ;
}
2016-01-29 04:04:39 +00:00
/* TODO: overflow check of stix->c->mth.balit_count itself */
2015-06-23 14:00:26 +00:00
stix - > c - > mth . balit [ stix - > c - > mth . balit_count + + ] = b ;
return 0 ;
}
2016-01-29 04:04:39 +00:00
static int add_to_array_literal_buffer ( stix_t * stix , stix_oop_t item )
2015-06-23 14:00:26 +00:00
{
if ( stix - > c - > mth . arlit_count > = stix - > c - > mth . arlit_capa )
{
stix_oop_t * tmp ;
2015-12-17 16:11:10 +00:00
stix_oow_t new_capa ;
2015-06-23 14:00:26 +00:00
new_capa = STIX_ALIGN ( stix - > c - > mth . arlit_count + 1 , ARLIT_BUFFER_ALIGN ) ;
tmp = ( stix_oop_t * ) stix_reallocmem ( stix , stix - > c - > mth . arlit , new_capa * STIX_SIZEOF ( * tmp ) ) ;
if ( ! tmp ) return - 1 ;
stix - > c - > mth . arlit_capa = new_capa ;
stix - > c - > mth . arlit = tmp ;
}
2015-07-14 13:35:18 +00:00
/* TODO: overflow check of stix->c->mth.arlit_count itself */
2015-06-23 14:00:26 +00:00
stix - > c - > mth . arlit [ stix - > c - > mth . arlit_count + + ] = item ;
return 0 ;
}
2015-07-15 08:39:18 +00:00
static int __read_byte_array_literal ( stix_t * stix , stix_oop_t * xlit )
2015-06-23 14:00:26 +00:00
{
stix_ooi_t tmp ;
stix_oop_t ba ;
stix - > c - > mth . balit_count = 0 ;
2016-08-29 07:39:09 +00:00
while ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_NUMLIT | | TOKEN_TYPE ( stix ) = = STIX_IOTOK_RADNUMLIT )
2015-06-23 14:00:26 +00:00
{
/* TODO: check if the number is an integer */
2016-09-06 16:06:22 +00:00
if ( string_to_smooi ( stix , TOKEN_NAME ( stix ) , TOKEN_TYPE ( stix ) = = STIX_IOTOK_RADNUMLIT , & tmp ) < = - 1 )
2015-06-23 14:00:26 +00:00
{
/* the token reader reads a valid token. no other errors
* than the range error must not occur */
STIX_ASSERT ( stix - > errnum = = STIX_ERANGE ) ;
2015-11-20 09:05:55 +00:00
/* if the token is out of the SMOOI range, it's too big or
* to small to be a byte */
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_BYTERANGE , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-06-23 14:00:26 +00:00
return - 1 ;
}
else if ( tmp < 0 | | tmp > 255 )
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_BYTERANGE , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-06-23 14:00:26 +00:00
return - 1 ;
}
2016-01-29 04:04:39 +00:00
if ( add_to_byte_array_literal_buffer ( stix , tmp ) < = - 1 ) return - 1 ;
2015-06-23 14:00:26 +00:00
GET_TOKEN ( stix ) ;
}
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) ! = STIX_IOTOK_RBRACK )
2015-06-23 14:00:26 +00:00
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_RBRACK , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-06-23 14:00:26 +00:00
return - 1 ;
}
ba = stix_instantiate ( stix , stix - > _byte_array , stix - > c - > mth . balit , stix - > c - > mth . balit_count ) ;
if ( ! ba ) return - 1 ;
* xlit = ba ;
return 0 ;
}
struct arlit_info_t
{
2015-12-17 16:11:10 +00:00
stix_oow_t pos ;
stix_oow_t len ;
2015-06-23 14:00:26 +00:00
} ;
typedef struct arlit_info_t arlit_info_t ;
2015-07-15 08:39:18 +00:00
static int __read_array_literal ( stix_t * stix , stix_oop_t * xlit )
2015-06-23 14:00:26 +00:00
{
stix_oop_t lit , a ;
2015-12-17 16:11:10 +00:00
stix_oow_t i , saved_arlit_count ;
2015-06-23 14:00:26 +00:00
arlit_info_t info ;
info . pos = stix - > c - > mth . arlit_count ;
info . len = 0 ;
do
{
2016-09-06 16:06:22 +00:00
switch ( TOKEN_TYPE ( stix ) )
2015-06-23 14:00:26 +00:00
{
/* TODO: floating pointer number */
case STIX_IOTOK_NUMLIT :
case STIX_IOTOK_RADNUMLIT :
2016-08-29 07:39:09 +00:00
lit = string_to_num ( stix , TOKEN_NAME ( stix ) , TOKEN_TYPE ( stix ) = = STIX_IOTOK_RADNUMLIT ) ;
2015-06-23 14:00:26 +00:00
break ;
2015-06-24 11:53:19 +00:00
case STIX_IOTOK_CHARLIT :
STIX_ASSERT ( stix - > c - > tok . name . len = = 1 ) ;
2015-11-20 09:05:55 +00:00
lit = STIX_CHAR_TO_OOP ( stix - > c - > tok . name . ptr [ 0 ] ) ;
2015-06-23 14:00:26 +00:00
break ;
case STIX_IOTOK_STRLIT :
lit = stix_instantiate ( stix , stix - > _string , stix - > c - > tok . name . ptr , stix - > c - > tok . name . len ) ;
break ;
case STIX_IOTOK_IDENT :
2015-07-10 14:06:07 +00:00
case STIX_IOTOK_IDENT_DOTTED :
2015-06-23 14:00:26 +00:00
case STIX_IOTOK_BINSEL :
case STIX_IOTOK_KEYWORD :
case STIX_IOTOK_SYMLIT :
case STIX_IOTOK_SELF :
case STIX_IOTOK_SUPER :
case STIX_IOTOK_THIS_CONTEXT :
2016-07-05 15:22:29 +00:00
case STIX_IOTOK_THIS_PROCESS :
2015-06-23 14:00:26 +00:00
lit = stix_makesymbol ( stix , stix - > c - > tok . name . ptr , stix - > c - > tok . name . len ) ;
break ;
case STIX_IOTOK_NIL :
lit = stix - > _nil ;
break ;
case STIX_IOTOK_TRUE :
lit = stix - > _true ;
break ;
case STIX_IOTOK_FALSE :
lit = stix - > _false ;
break ;
2016-09-06 16:06:22 +00:00
case STIX_IOTOK_ARPAREN : /* #( */
2015-06-23 14:00:26 +00:00
case STIX_IOTOK_LPAREN : /* ( */
saved_arlit_count = stix - > c - > mth . arlit_count ;
/* TODO: get rid of recursion?? */
GET_TOKEN ( stix ) ;
2015-07-15 08:39:18 +00:00
if ( __read_array_literal ( stix , & lit ) < = - 1 ) return - 1 ;
2015-06-23 14:00:26 +00:00
stix - > c - > mth . arlit_count = saved_arlit_count ;
break ;
2016-09-06 16:06:22 +00:00
case STIX_IOTOK_BAPAREN : /* #[ */
2015-06-23 14:00:26 +00:00
case STIX_IOTOK_LBRACK : /* [ */
GET_TOKEN ( stix ) ;
2015-07-15 08:39:18 +00:00
if ( __read_byte_array_literal ( stix , & lit ) < = - 1 ) return - 1 ;
2015-06-23 14:00:26 +00:00
break ;
default :
goto done ;
}
2016-01-29 04:04:39 +00:00
if ( ! lit | | add_to_array_literal_buffer ( stix , lit ) < = - 1 ) return - 1 ;
2015-06-23 14:00:26 +00:00
info . len + + ;
GET_TOKEN ( stix ) ;
}
while ( 1 ) ;
done :
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) ! = STIX_IOTOK_RPAREN )
2015-06-23 14:00:26 +00:00
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_RPAREN , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-06-23 14:00:26 +00:00
return - 1 ;
}
a = stix_instantiate ( stix , stix - > _array , STIX_NULL , info . len ) ;
if ( ! a ) return - 1 ;
for ( i = 0 ; i < info . len ; i + + )
{
( ( stix_oop_oop_t ) a ) - > slot [ i ] = stix - > c - > mth . arlit [ info . pos + i ] ;
}
* xlit = a ;
return 0 ;
}
2015-07-15 08:39:18 +00:00
static STIX_INLINE int read_byte_array_literal ( stix_t * stix , stix_oop_t * xlit )
{
GET_TOKEN ( stix ) ; /* skip #[ and read the next token */
return __read_byte_array_literal ( stix , xlit ) ;
}
2015-06-23 14:00:26 +00:00
static int compile_byte_array_literal ( stix_t * stix )
{
stix_oop_t lit ;
2015-12-17 16:11:10 +00:00
stix_oow_t index ;
2015-06-23 14:00:26 +00:00
2015-07-15 08:39:18 +00:00
if ( read_byte_array_literal ( stix , & lit ) < = - 1 | |
add_literal ( stix , lit , & index ) < = - 1 | |
emit_single_param_instruction ( stix , BCODE_PUSH_LITERAL_0 , index ) < = - 1 ) return - 1 ;
2015-06-23 14:00:26 +00:00
GET_TOKEN ( stix ) ;
return 0 ;
}
2015-07-15 08:39:18 +00:00
static int read_array_literal ( stix_t * stix , stix_oop_t * xlit )
2015-06-23 14:00:26 +00:00
{
int x ;
2015-12-17 16:11:10 +00:00
stix_oow_t saved_arlit_count ;
2015-06-23 14:00:26 +00:00
stix - > c - > in_array = 1 ;
2015-07-15 08:39:18 +00:00
if ( get_token ( stix ) < = - 1 )
{
/* skip #( and read the next token */
stix - > c - > in_array = 0 ;
return - 1 ;
}
saved_arlit_count = stix - > c - > mth . arlit_count ;
x = __read_array_literal ( stix , xlit ) ;
stix - > c - > mth . arlit_count = saved_arlit_count ;
2015-06-23 14:00:26 +00:00
stix - > c - > in_array = 0 ;
2015-07-15 08:39:18 +00:00
return x ;
}
static int compile_array_literal ( stix_t * stix )
{
stix_oop_t lit ;
2015-12-17 16:11:10 +00:00
stix_oow_t index ;
2015-07-15 08:39:18 +00:00
STIX_ASSERT ( stix - > c - > mth . arlit_count = = 0 ) ;
if ( read_array_literal ( stix , & lit ) < = - 1 | |
add_literal ( stix , lit , & index ) < = - 1 | |
emit_single_param_instruction ( stix , BCODE_PUSH_LITERAL_0 , index ) < = - 1 ) return - 1 ;
2015-06-23 14:00:26 +00:00
GET_TOKEN ( stix ) ;
return 0 ;
}
2015-10-28 14:58:58 +00:00
static int compile_expression_primary ( stix_t * stix , const stix_oocs_t * ident , const stix_ioloc_t * ident_loc , int ident_dotted , int * to_super )
2015-06-03 04:22:19 +00:00
{
/*
* expression - primary : = identifier | literal | block - constructor | ( " ( " method - expression " ) " )
*/
var_info_t var ;
2015-06-03 17:24:11 +00:00
int read_next_token = 0 ;
2015-12-17 16:11:10 +00:00
stix_oow_t index ;
2015-06-03 17:24:11 +00:00
* to_super = 0 ;
2015-06-03 04:22:19 +00:00
if ( ident )
2015-06-01 15:59:16 +00:00
{
2015-06-03 17:24:11 +00:00
/* the caller has read the identifier and the next word */
handle_ident :
2015-07-10 14:06:07 +00:00
if ( get_variable_info ( stix , ident , ident_loc , ident_dotted , & var ) < = - 1 ) return - 1 ;
2015-06-03 17:24:11 +00:00
switch ( var . type )
{
case VAR_ARGUMENT :
case VAR_TEMPORARY :
2015-06-30 14:47:39 +00:00
{
# if defined(STIX_USE_CTXTEMPVAR)
if ( stix - > c - > mth . blk_depth > 0 )
{
2015-12-17 16:11:10 +00:00
stix_oow_t i ;
2015-06-30 14:47:39 +00:00
2016-01-29 04:04:39 +00:00
/* if a temporary variable is accessed inside a block,
* use a special instruction to indicate it */
2015-06-30 14:47:39 +00:00
STIX_ASSERT ( var . pos < stix - > c - > mth . blk_tmprcnt [ stix - > c - > mth . blk_depth ] ) ;
for ( i = stix - > c - > mth . blk_depth ; i > 0 ; i - - )
{
if ( var . pos > = stix - > c - > mth . blk_tmprcnt [ i - 1 ] )
{
if ( emit_double_param_instruction ( stix , BCODE_PUSH_CTXTEMPVAR_0 , stix - > c - > mth . blk_depth - i , var . pos - stix - > c - > mth . blk_tmprcnt [ i - 1 ] ) < = - 1 ) return - 1 ;
goto temporary_done ;
}
}
}
# endif
2015-06-29 13:52:40 +00:00
if ( emit_single_param_instruction ( stix , BCODE_PUSH_TEMPVAR_0 , var . pos ) < = - 1 ) return - 1 ;
2015-06-30 14:47:39 +00:00
temporary_done :
2015-06-03 17:24:11 +00:00
break ;
2015-06-30 14:47:39 +00:00
}
2015-06-03 17:24:11 +00:00
case VAR_INSTANCE :
case VAR_CLASSINST :
2015-06-29 13:52:40 +00:00
if ( emit_single_param_instruction ( stix , BCODE_PUSH_INSTVAR_0 , var . pos ) < = - 1 ) return - 1 ;
2015-06-03 17:24:11 +00:00
break ;
case VAR_CLASS :
2015-06-12 13:52:30 +00:00
if ( add_literal ( stix , ( stix_oop_t ) var . cls , & index ) < = - 1 | |
2015-06-29 13:52:40 +00:00
emit_double_param_instruction ( stix , BCODE_PUSH_OBJVAR_0 , var . pos , index ) < = - 1 ) return - 1 ;
2015-06-12 13:52:30 +00:00
break ;
2015-06-03 17:24:11 +00:00
case VAR_GLOBAL :
2015-06-30 14:47:39 +00:00
/* [NOTE]
* the association object pointed to by a system dictionary
* is stored into the literal frame . so the system dictionary
* must not migrate the value of the association to a new
* association when it rehashes the entire dictionary .
* If the association entry is deleted from the dictionary ,
* the code compiled before the deletion will still access
* the deleted association
*/
if ( add_literal ( stix , ( stix_oop_t ) var . gbl , & index ) < = - 1 | |
emit_single_param_instruction ( stix , BCODE_PUSH_OBJECT_0 , index ) < = - 1 ) return - 1 ;
break ;
2015-06-03 17:24:11 +00:00
default :
stix - > errnum = STIX_EINTERN ;
return - 1 ;
}
if ( read_next_token ) GET_TOKEN ( stix ) ;
2015-06-03 04:22:19 +00:00
}
else
{
2016-09-06 16:06:22 +00:00
switch ( TOKEN_TYPE ( stix ) )
2015-06-01 16:59:07 +00:00
{
2015-07-10 14:06:07 +00:00
case STIX_IOTOK_IDENT_DOTTED :
2015-10-03 15:29:03 +00:00
ident_dotted = 1 ;
2015-06-03 04:22:19 +00:00
case STIX_IOTOK_IDENT :
2016-08-29 07:39:09 +00:00
ident = TOKEN_NAME ( stix ) ;
ident_loc = TOKEN_LOC ( stix ) ;
2015-06-03 17:24:11 +00:00
read_next_token = 1 ;
2015-06-03 04:22:19 +00:00
goto handle_ident ;
2015-06-01 16:59:07 +00:00
2015-06-03 04:22:19 +00:00
case STIX_IOTOK_SELF :
2015-06-29 13:52:40 +00:00
if ( emit_byte_instruction ( stix , BCODE_PUSH_RECEIVER ) < = - 1 ) return - 1 ;
2015-06-03 17:24:11 +00:00
GET_TOKEN ( stix ) ;
2015-06-03 04:22:19 +00:00
break ;
2015-06-01 16:59:07 +00:00
2015-06-03 04:22:19 +00:00
case STIX_IOTOK_SUPER :
2015-06-29 13:52:40 +00:00
if ( emit_byte_instruction ( stix , BCODE_PUSH_RECEIVER ) < = - 1 ) return - 1 ;
2015-06-03 17:24:11 +00:00
GET_TOKEN ( stix ) ;
* to_super = 1 ;
2015-06-03 04:22:19 +00:00
break ;
2015-06-01 15:59:16 +00:00
2015-06-03 04:22:19 +00:00
case STIX_IOTOK_NIL :
2015-06-29 13:52:40 +00:00
if ( emit_byte_instruction ( stix , BCODE_PUSH_NIL ) < = - 1 ) return - 1 ;
2015-06-03 17:24:11 +00:00
GET_TOKEN ( stix ) ;
2015-06-03 04:22:19 +00:00
break ;
2015-06-01 16:59:07 +00:00
2015-06-03 04:22:19 +00:00
case STIX_IOTOK_TRUE :
2015-06-29 13:52:40 +00:00
if ( emit_byte_instruction ( stix , BCODE_PUSH_TRUE ) < = - 1 ) return - 1 ;
2015-06-03 17:24:11 +00:00
GET_TOKEN ( stix ) ;
2015-06-03 04:22:19 +00:00
break ;
2015-06-01 15:59:16 +00:00
2015-06-03 04:22:19 +00:00
case STIX_IOTOK_FALSE :
2015-06-29 13:52:40 +00:00
if ( emit_byte_instruction ( stix , BCODE_PUSH_FALSE ) < = - 1 ) return - 1 ;
2015-06-03 17:24:11 +00:00
GET_TOKEN ( stix ) ;
2015-06-03 04:22:19 +00:00
break ;
2015-06-01 15:59:16 +00:00
2015-06-03 04:22:19 +00:00
case STIX_IOTOK_THIS_CONTEXT :
2015-06-29 13:52:40 +00:00
if ( emit_byte_instruction ( stix , BCODE_PUSH_CONTEXT ) < = - 1 ) return - 1 ;
2015-06-03 17:24:11 +00:00
GET_TOKEN ( stix ) ;
2015-06-03 04:22:19 +00:00
break ;
2016-07-05 15:22:29 +00:00
case STIX_IOTOK_THIS_PROCESS :
if ( emit_byte_instruction ( stix , BCODE_PUSH_PROCESS ) < = - 1 ) return - 1 ;
GET_TOKEN ( stix ) ;
break ;
2015-06-24 11:53:19 +00:00
case STIX_IOTOK_CHARLIT :
STIX_ASSERT ( stix - > c - > tok . name . len = = 1 ) ;
if ( add_character_literal ( stix , stix - > c - > tok . name . ptr [ 0 ] , & index ) < = - 1 | |
2015-06-29 13:52:40 +00:00
emit_single_param_instruction ( stix , BCODE_PUSH_LITERAL_0 , index ) < = - 1 ) return - 1 ;
2015-06-03 04:22:19 +00:00
GET_TOKEN ( stix ) ;
break ;
case STIX_IOTOK_STRLIT :
2016-08-29 07:39:09 +00:00
if ( add_string_literal ( stix , TOKEN_NAME ( stix ) , & index ) < = - 1 | |
2015-06-29 13:52:40 +00:00
emit_single_param_instruction ( stix , BCODE_PUSH_LITERAL_0 , index ) < = - 1 ) return - 1 ;
2015-06-03 04:22:19 +00:00
GET_TOKEN ( stix ) ;
break ;
case STIX_IOTOK_SYMLIT :
2016-08-29 07:39:09 +00:00
if ( add_symbol_literal ( stix , TOKEN_NAME ( stix ) , & index ) < = - 1 | |
2015-06-29 13:52:40 +00:00
emit_single_param_instruction ( stix , BCODE_PUSH_LITERAL_0 , index ) < = - 1 ) return - 1 ;
2015-06-03 04:22:19 +00:00
GET_TOKEN ( stix ) ;
break ;
case STIX_IOTOK_NUMLIT :
2015-06-16 13:29:29 +00:00
case STIX_IOTOK_RADNUMLIT :
2015-06-03 04:22:19 +00:00
{
2015-11-20 09:05:55 +00:00
/* TODO: floating pointer number */
/* TODO: other types of numbers, etc */
2015-11-12 06:57:35 +00:00
stix_oop_t tmp ;
2015-12-02 16:14:37 +00:00
2016-08-29 07:39:09 +00:00
tmp = string_to_num ( stix , TOKEN_NAME ( stix ) , TOKEN_TYPE ( stix ) = = STIX_IOTOK_RADNUMLIT ) ;
2015-11-12 06:57:35 +00:00
if ( ! tmp ) return - 1 ;
if ( STIX_OOP_IS_SMOOI ( tmp ) )
{
if ( emit_push_smint_literal ( stix , STIX_OOP_TO_SMOOI ( tmp ) ) < = - 1 ) return - 1 ;
}
else
{
if ( add_literal ( stix , tmp , & index ) < = - 1 | |
emit_single_param_instruction ( stix , BCODE_PUSH_LITERAL_0 , index ) < = - 1 ) return - 1 ;
}
2015-06-03 04:22:19 +00:00
GET_TOKEN ( stix ) ;
break ;
}
2016-09-06 16:06:22 +00:00
case STIX_IOTOK_BAPAREN : /* #[ */
2015-06-23 14:00:26 +00:00
/*GET_TOKEN (stix);*/
if ( compile_byte_array_literal ( stix ) < = - 1 ) return - 1 ;
2015-06-03 04:22:19 +00:00
break ;
2016-09-06 16:06:22 +00:00
case STIX_IOTOK_ARPAREN : /* #( */
2015-06-23 14:00:26 +00:00
/*GET_TOKEN (stix);*/
if ( compile_array_literal ( stix ) < = - 1 ) return - 1 ;
2015-06-03 04:22:19 +00:00
break ;
2015-06-23 14:00:26 +00:00
/* TODO: dynamic array, non constant array #<> or #{} or what is a better bracket? */
case STIX_IOTOK_LBRACK : /* [ */
2015-06-30 14:47:39 +00:00
{
int n ;
2015-06-16 13:29:29 +00:00
/*GET_TOKEN (stix);*/
2015-06-30 14:47:39 +00:00
if ( store_tmpr_count_for_block ( stix , stix - > c - > mth . tmpr_count ) < = - 1 ) return - 1 ;
stix - > c - > mth . blk_depth + + ;
/*
* stix - > c - > mth . tmpr_count [ 0 ] contains the number of temporaries for a method .
* stix - > c - > mth . tmpr_count [ 1 ] contains the number of temporaries for the block plus the containing method .
* . . .
2015-06-30 15:12:37 +00:00
* stix - > c - > mth . tmpr_count [ n ] contains the number of temporaries for the block plus all containing method and blocks .
2015-06-30 14:47:39 +00:00
*/
n = compile_block_expression ( stix ) ;
stix - > c - > mth . blk_depth - - ;
if ( n < = - 1 ) return - 1 ;
2015-06-03 04:22:19 +00:00
break ;
2015-06-30 14:47:39 +00:00
}
2015-06-03 04:22:19 +00:00
case STIX_IOTOK_LPAREN :
GET_TOKEN ( stix ) ;
2015-06-11 09:11:18 +00:00
if ( compile_method_expression ( stix , 0 ) < = - 1 ) return - 1 ;
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) ! = STIX_IOTOK_RPAREN )
2015-06-03 04:22:19 +00:00
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_RPAREN , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-06-03 04:22:19 +00:00
return - 1 ;
}
GET_TOKEN ( stix ) ;
break ;
default :
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_PRIMARY , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-06-03 04:22:19 +00:00
return - 1 ;
}
2015-06-01 15:59:16 +00:00
}
2015-06-03 04:22:19 +00:00
return 0 ;
}
2015-06-01 15:59:16 +00:00
2015-10-29 15:24:46 +00:00
static stix_oob_t send_message_cmd [ ] =
2015-06-03 17:24:11 +00:00
{
2015-06-29 13:52:40 +00:00
BCODE_SEND_MESSAGE_0 ,
BCODE_SEND_MESSAGE_TO_SUPER_0
2015-06-03 17:24:11 +00:00
} ;
2015-06-22 14:21:46 +00:00
static int compile_unary_message ( stix_t * stix , int to_super )
{
2015-12-17 16:11:10 +00:00
stix_oow_t index ;
2015-06-22 14:21:46 +00:00
2016-08-29 07:39:09 +00:00
STIX_ASSERT ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_IDENT ) ;
2015-06-22 14:21:46 +00:00
do
{
2016-08-29 07:39:09 +00:00
if ( add_symbol_literal ( stix , TOKEN_NAME ( stix ) , & index ) < = - 1 | |
2015-06-29 13:52:40 +00:00
emit_double_param_instruction ( stix , send_message_cmd [ to_super ] , 0 , index ) < = - 1 ) return - 1 ;
2015-06-22 14:21:46 +00:00
GET_TOKEN ( stix ) ;
}
2016-08-29 07:39:09 +00:00
while ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_IDENT ) ;
2015-06-22 14:21:46 +00:00
return 0 ;
}
static int compile_binary_message ( stix_t * stix , int to_super )
{
/*
* binary - message : = binary - selector binary - argument
* binary - argument : = expression - primary unary - message *
*/
2015-12-17 16:11:10 +00:00
stix_oow_t index ;
2015-06-22 14:21:46 +00:00
int to_super2 ;
2015-10-28 14:58:58 +00:00
stix_oocs_t binsel ;
2015-12-17 16:11:10 +00:00
stix_oow_t saved_binsels_len , binsel_offset ;
2015-06-22 14:21:46 +00:00
2016-08-29 07:39:09 +00:00
STIX_ASSERT ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_BINSEL ) ;
2015-06-22 14:21:46 +00:00
do
{
binsel = stix - > c - > tok . name ;
saved_binsels_len = stix - > c - > mth . binsels . len ;
2015-07-01 15:01:39 +00:00
if ( clone_binary_selector ( stix , & binsel , & binsel_offset ) < = - 1 ) goto oops ;
2015-06-22 14:21:46 +00:00
GET_TOKEN ( stix ) ;
2015-07-10 14:06:07 +00:00
if ( compile_expression_primary ( stix , STIX_NULL , STIX_NULL , 0 , & to_super2 ) < = - 1 ) goto oops ;
2015-06-22 14:21:46 +00:00
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_IDENT & & compile_unary_message ( stix , to_super2 ) < = - 1 ) goto oops ;
2015-06-22 14:21:46 +00:00
2015-07-01 15:01:39 +00:00
/* update the pointer to the cloned selector now
* to be free from reallocation risk for the recursive call
* to compile_expression_primary ( ) . */
binsel . ptr = & stix - > c - > mth . binsels . ptr [ binsel_offset ] ;
2015-06-22 14:21:46 +00:00
if ( add_symbol_literal ( stix , & binsel , & index ) < = - 1 | |
2015-06-29 13:52:40 +00:00
emit_double_param_instruction ( stix , send_message_cmd [ to_super ] , 1 , index ) < = - 1 ) goto oops ;
2015-06-22 14:21:46 +00:00
stix - > c - > mth . binsels . len = saved_binsels_len ;
}
2016-08-29 07:39:09 +00:00
while ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_BINSEL ) ;
2015-06-22 14:21:46 +00:00
return 0 ;
oops :
stix - > c - > mth . binsels . len = saved_binsels_len ;
return - 1 ;
}
static int compile_keyword_message ( stix_t * stix , int to_super )
{
/*
* keyword - message : = ( keyword keyword - argument ) +
* keyword - argument : = expression - primary unary - message * binary - message *
*/
2015-12-17 16:11:10 +00:00
stix_oow_t index ;
2015-06-22 14:21:46 +00:00
int to_super2 ;
2015-10-28 14:58:58 +00:00
stix_oocs_t kw , kwsel ;
2015-06-22 14:21:46 +00:00
stix_ioloc_t saved_kwsel_loc ;
2015-12-17 16:11:10 +00:00
stix_oow_t saved_kwsel_len ;
stix_oow_t kw_offset ;
stix_oow_t nargs = 0 ;
2015-06-22 14:21:46 +00:00
saved_kwsel_loc = stix - > c - > tok . loc ;
saved_kwsel_len = stix - > c - > mth . kwsels . len ;
2016-05-07 01:37:44 +00:00
/* TODO: optimization for ifTrue: ifFalse: whileTrue: whileFalse .. */
2015-06-22 14:21:46 +00:00
do
{
kw = stix - > c - > tok . name ;
2015-07-01 15:01:39 +00:00
if ( clone_keyword ( stix , & kw , & kw_offset ) < = - 1 ) goto oops ;
2015-06-22 14:21:46 +00:00
GET_TOKEN ( stix ) ;
2015-07-10 14:06:07 +00:00
if ( compile_expression_primary ( stix , STIX_NULL , STIX_NULL , 0 , & to_super2 ) < = - 1 ) goto oops ;
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_IDENT & & compile_unary_message ( stix , to_super2 ) < = - 1 ) goto oops ;
if ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_BINSEL & & compile_binary_message ( stix , to_super2 ) < = - 1 ) goto oops ;
2015-06-22 14:21:46 +00:00
2015-07-01 15:01:39 +00:00
kw . ptr = & stix - > c - > mth . kwsels . ptr [ kw_offset ] ;
2015-06-22 14:21:46 +00:00
if ( nargs > = MAX_CODE_NARGS )
{
/* 'kw' points to only one segment of the full keyword message.
* if it parses an expression like ' aBlock value : 10 with : 20 ' ,
* ' kw ' may point to ' value : ' or ' with : ' .
*/
set_syntax_error ( stix , STIX_SYNERR_ARGFLOOD , & saved_kwsel_loc , & kw ) ;
goto oops ;
}
nargs + + ;
}
2016-08-29 07:39:09 +00:00
while ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_KEYWORD ) ;
2015-06-22 14:21:46 +00:00
kwsel . ptr = & stix - > c - > mth . kwsels . ptr [ saved_kwsel_len ] ;
kwsel . len = stix - > c - > mth . kwsels . len - saved_kwsel_len ;
if ( add_symbol_literal ( stix , & kwsel , & index ) < = - 1 | |
2015-06-29 13:52:40 +00:00
emit_double_param_instruction ( stix , send_message_cmd [ to_super ] , nargs , index ) < = - 1 ) goto oops ;
2015-06-22 14:21:46 +00:00
stix - > c - > mth . kwsels . len = saved_kwsel_len ;
return 0 ;
oops :
stix - > c - > mth . kwsels . len = saved_kwsel_len ;
return - 1 ;
}
2015-06-03 17:24:11 +00:00
static int compile_message_expression ( stix_t * stix , int to_super )
{
/*
* message - expression : = single - message cascaded - message
* single - message : =
* ( unary - message + binary - message * keyword - message ? ) |
* ( binary - message + keyword - message ? ) |
* keyword - message
*
* keyword - message : = ( keyword keyword - argument ) +
* keyword - argument : = expression - primary unary - message * binary - message *
* binary - message : = binary - selector binary - argument
* binary - argument : = expression - primary unary - message *
* unary - message : = unary - selector
* cascaded - message : = ( " ; " single - message ) *
*/
2015-12-17 16:11:10 +00:00
stix_oow_t noop_pos ;
2015-06-03 17:24:11 +00:00
2015-06-22 14:21:46 +00:00
do
{
2016-09-06 16:06:22 +00:00
switch ( TOKEN_TYPE ( stix ) )
2015-06-22 14:21:46 +00:00
{
case STIX_IOTOK_IDENT :
/* insert NOOP to change to DUP_STACKTOP if there is a
* cascaded message */
noop_pos = stix - > c - > mth . code . len ;
2015-06-29 13:52:40 +00:00
if ( emit_byte_instruction ( stix , BCODE_NOOP ) < = - 1 ) return - 1 ;
2015-06-22 14:21:46 +00:00
if ( compile_unary_message ( stix , to_super ) < = - 1 ) return - 1 ;
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_BINSEL )
2015-06-22 14:21:46 +00:00
{
2015-06-30 14:47:39 +00:00
STIX_ASSERT ( stix - > c - > mth . code . len > noop_pos ) ;
STIX_MEMMOVE ( & stix - > c - > mth . code . ptr [ noop_pos ] , & stix - > c - > mth . code . ptr [ noop_pos + 1 ] , stix - > c - > mth . code . len - noop_pos - 1 ) ;
stix - > c - > mth . code . len - - ;
2015-06-22 14:21:46 +00:00
2015-06-30 14:47:39 +00:00
noop_pos = stix - > c - > mth . code . len ;
if ( emit_byte_instruction ( stix , BCODE_NOOP ) < = - 1 ) return - 1 ;
2015-06-22 14:21:46 +00:00
if ( compile_binary_message ( stix , to_super ) < = - 1 ) return - 1 ;
}
2015-06-30 14:47:39 +00:00
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_KEYWORD )
2015-06-22 14:21:46 +00:00
{
2015-06-30 14:47:39 +00:00
STIX_ASSERT ( stix - > c - > mth . code . len > noop_pos ) ;
STIX_MEMMOVE ( & stix - > c - > mth . code . ptr [ noop_pos ] , & stix - > c - > mth . code . ptr [ noop_pos + 1 ] , stix - > c - > mth . code . len - noop_pos - 1 ) ;
stix - > c - > mth . code . len - - ;
2015-06-22 14:21:46 +00:00
2015-06-30 14:47:39 +00:00
noop_pos = stix - > c - > mth . code . len ;
if ( emit_byte_instruction ( stix , BCODE_NOOP ) < = - 1 ) return - 1 ;
2015-06-22 14:21:46 +00:00
if ( compile_keyword_message ( stix , to_super ) < = - 1 ) return - 1 ;
}
break ;
case STIX_IOTOK_BINSEL :
noop_pos = stix - > c - > mth . code . len ;
2015-06-29 13:52:40 +00:00
if ( emit_byte_instruction ( stix , BCODE_NOOP ) < = - 1 ) return - 1 ;
2015-06-22 14:21:46 +00:00
if ( compile_binary_message ( stix , to_super ) < = - 1 ) return - 1 ;
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_KEYWORD )
2015-06-22 14:21:46 +00:00
{
2015-06-30 14:47:39 +00:00
STIX_ASSERT ( stix - > c - > mth . code . len > noop_pos ) ;
STIX_MEMMOVE ( & stix - > c - > mth . code . ptr [ noop_pos ] , & stix - > c - > mth . code . ptr [ noop_pos + 1 ] , stix - > c - > mth . code . len - noop_pos - 1 ) ;
stix - > c - > mth . code . len - - ;
2015-06-22 14:21:46 +00:00
2015-06-30 14:47:39 +00:00
noop_pos = stix - > c - > mth . code . len ;
if ( emit_byte_instruction ( stix , BCODE_NOOP ) < = - 1 ) return - 1 ;
2015-06-22 14:21:46 +00:00
if ( compile_keyword_message ( stix , to_super ) < = - 1 ) return - 1 ;
}
break ;
case STIX_IOTOK_KEYWORD :
noop_pos = stix - > c - > mth . code . len ;
2015-06-29 13:52:40 +00:00
if ( emit_byte_instruction ( stix , BCODE_NOOP ) < = - 1 ) return - 1 ;
2015-06-22 14:21:46 +00:00
if ( compile_keyword_message ( stix , to_super ) < = - 1 ) return - 1 ;
break ;
default :
goto done ;
}
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_SEMICOLON )
2015-06-22 14:21:46 +00:00
{
2015-06-29 13:52:40 +00:00
stix - > c - > mth . code . ptr [ noop_pos ] = BCODE_DUP_STACKTOP ;
if ( emit_byte_instruction ( stix , BCODE_POP_STACKTOP ) < = - 1 ) return - 1 ;
2015-06-22 14:21:46 +00:00
GET_TOKEN ( stix ) ;
}
else
{
/* delete the NOOP instruction inserted */
STIX_ASSERT ( stix - > c - > mth . code . len > noop_pos ) ;
STIX_MEMMOVE ( & stix - > c - > mth . code . ptr [ noop_pos ] , & stix - > c - > mth . code . ptr [ noop_pos + 1 ] , stix - > c - > mth . code . len - noop_pos - 1 ) ;
stix - > c - > mth . code . len - - ;
goto done ;
}
}
while ( 1 ) ;
done :
2015-06-03 17:24:11 +00:00
return 0 ;
}
2015-06-01 15:59:16 +00:00
2015-10-28 14:58:58 +00:00
static int compile_basic_expression ( stix_t * stix , const stix_oocs_t * ident , const stix_ioloc_t * ident_loc , int ident_dotted )
2015-06-03 04:22:19 +00:00
{
/*
2015-06-03 17:24:11 +00:00
* basic - expression : = expression - primary message - expression ?
2015-06-03 04:22:19 +00:00
*/
2015-06-03 17:24:11 +00:00
int to_super ;
2015-06-03 04:22:19 +00:00
2015-07-10 14:06:07 +00:00
if ( compile_expression_primary ( stix , ident , ident_loc , ident_dotted , & to_super ) < = - 1 ) return - 1 ;
2016-02-11 14:26:26 +00:00
#if 0
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) ! = STIX_IOTOK_EOF & &
TOKEN_TYPE ( stix ) ! = STIX_IOTOK_RBRACE & &
TOKEN_TYPE ( stix ) ! = STIX_IOTOK_PERIOD & &
TOKEN_TYPE ( stix ) ! = STIX_IOTOK_SEMICOLON )
2015-06-03 04:22:19 +00:00
{
2015-06-03 17:24:11 +00:00
if ( compile_message_expression ( stix , to_super ) < = - 1 ) return - 1 ;
2015-06-03 04:22:19 +00:00
}
2016-02-11 14:26:26 +00:00
# else
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_IDENT | |
TOKEN_TYPE ( stix ) = = STIX_IOTOK_BINSEL | |
TOKEN_TYPE ( stix ) = = STIX_IOTOK_KEYWORD )
2016-02-11 14:26:26 +00:00
{
if ( compile_message_expression ( stix , to_super ) < = - 1 ) return - 1 ;
}
# endif
2015-06-03 04:22:19 +00:00
return 0 ;
2015-06-01 15:59:16 +00:00
}
2015-06-11 09:11:18 +00:00
static int compile_method_expression ( stix_t * stix , int pop )
2015-06-01 15:59:16 +00:00
{
/*
2015-06-03 04:22:19 +00:00
* method - expression : = method - assignment - expression | basic - expression
2015-06-01 15:59:16 +00:00
* method - assignment - expression : = identifier " := " method - expression
*/
2015-10-28 14:58:58 +00:00
stix_oocs_t assignee ;
2015-12-17 16:11:10 +00:00
stix_oow_t index ;
2015-06-11 09:11:18 +00:00
int ret = 0 ;
2015-06-01 15:59:16 +00:00
2015-06-11 09:11:18 +00:00
STIX_ASSERT ( pop = = 0 | | pop = = 1 ) ;
2015-06-03 17:24:11 +00:00
STIX_MEMSET ( & assignee , 0 , STIX_SIZEOF ( assignee ) ) ;
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_IDENT | |
TOKEN_TYPE ( stix ) = = STIX_IOTOK_IDENT_DOTTED )
2015-06-01 15:59:16 +00:00
{
stix_ioloc_t assignee_loc ;
2015-12-17 16:11:10 +00:00
stix_oow_t assignee_offset ;
2015-07-10 14:06:07 +00:00
int assignee_dotted ;
2015-07-01 15:01:39 +00:00
2015-06-01 15:59:16 +00:00
/* store the assignee name to the internal buffer
* to make it valid after the token buffer has been overwritten */
assignee = stix - > c - > tok . name ;
2015-07-01 15:01:39 +00:00
if ( clone_assignee ( stix , & assignee , & assignee_offset ) < = - 1 ) return - 1 ;
2015-06-01 15:59:16 +00:00
assignee_loc = stix - > c - > tok . loc ;
2016-08-29 07:39:09 +00:00
assignee_dotted = ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_IDENT_DOTTED ) ;
2015-05-25 17:10:49 +00:00
GET_TOKEN ( stix ) ;
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_ASSIGN )
2015-05-25 17:10:49 +00:00
{
2015-06-03 17:24:11 +00:00
/* assignment expression */
var_info_t var ;
2015-05-25 17:10:49 +00:00
GET_TOKEN ( stix ) ;
2015-06-03 17:24:11 +00:00
2015-07-01 15:01:39 +00:00
if ( compile_method_expression ( stix , 0 ) < = - 1 ) goto oops ;
/* compile_method_expression() is called after clone_assignee().
* clone_assignee ( ) may reallocate a single buffer to hold
* a series of assigness names . the pointer based operation is
* fragile as it can change . use the offset of the cloned
* assignee to update the actual pointer after the recursive
* compile_method_expression ( ) call */
assignee . ptr = & stix - > c - > mth . assignees . ptr [ assignee_offset ] ;
2015-07-10 14:06:07 +00:00
if ( get_variable_info ( stix , & assignee , & assignee_loc , assignee_dotted , & var ) < = - 1 ) goto oops ;
2015-06-03 17:24:11 +00:00
switch ( var . type )
{
case VAR_ARGUMENT :
/* assigning to an argument is not allowed */
set_syntax_error ( stix , STIX_SYNERR_VARARG , & assignee_loc , & assignee ) ;
2015-06-11 09:11:18 +00:00
goto oops ;
2015-06-03 17:24:11 +00:00
case VAR_TEMPORARY :
2015-06-30 14:47:39 +00:00
{
# if defined(STIX_USE_CTXTEMPVAR)
if ( stix - > c - > mth . blk_depth > 0 )
{
2015-12-17 16:11:10 +00:00
stix_oow_t i ;
2015-06-30 14:47:39 +00:00
2016-01-29 04:04:39 +00:00
/* if a temporary variable is accessed inside a block,
* use a special instruction to indicate it */
2015-06-30 14:47:39 +00:00
STIX_ASSERT ( var . pos < stix - > c - > mth . blk_tmprcnt [ stix - > c - > mth . blk_depth ] ) ;
for ( i = stix - > c - > mth . blk_depth ; i > 0 ; i - - )
{
if ( var . pos > = stix - > c - > mth . blk_tmprcnt [ i - 1 ] )
{
if ( emit_double_param_instruction ( stix , ( pop ? BCODE_POP_INTO_CTXTEMPVAR_0 : BCODE_STORE_INTO_CTXTEMPVAR_0 ) , stix - > c - > mth . blk_depth - i , var . pos - stix - > c - > mth . blk_tmprcnt [ i - 1 ] ) < = - 1 ) return - 1 ;
goto temporary_done ;
}
}
}
# endif
2015-06-29 14:24:04 +00:00
if ( emit_single_param_instruction ( stix , ( pop ? BCODE_POP_INTO_TEMPVAR_0 : BCODE_STORE_INTO_TEMPVAR_0 ) , var . pos ) < = - 1 ) goto oops ;
2015-06-30 14:47:39 +00:00
temporary_done :
2015-06-29 14:24:04 +00:00
ret = pop ;
2015-06-03 17:24:11 +00:00
break ;
2015-06-30 14:47:39 +00:00
}
2015-06-03 17:24:11 +00:00
case VAR_INSTANCE :
case VAR_CLASSINST :
2015-06-29 14:24:04 +00:00
if ( emit_single_param_instruction ( stix , ( pop ? BCODE_POP_INTO_INSTVAR_0 : BCODE_STORE_INTO_INSTVAR_0 ) , var . pos ) < = - 1 ) goto oops ;
ret = pop ;
2015-06-03 17:24:11 +00:00
break ;
case VAR_CLASS :
2015-06-12 13:52:30 +00:00
if ( add_literal ( stix , ( stix_oop_t ) var . cls , & index ) < = - 1 | |
2015-06-29 14:24:04 +00:00
emit_double_param_instruction ( stix , ( pop ? BCODE_POP_INTO_OBJVAR_0 : BCODE_STORE_INTO_OBJVAR_0 ) , var . pos , index ) < = - 1 ) goto oops ;
ret = pop ;
2015-06-12 13:52:30 +00:00
break ;
2015-06-03 17:24:11 +00:00
case VAR_GLOBAL :
2015-06-30 14:47:39 +00:00
if ( add_literal ( stix , ( stix_oop_t ) var . gbl , & index ) < = - 1 | |
emit_single_param_instruction ( stix , ( pop ? BCODE_POP_INTO_OBJECT_0 : BCODE_STORE_INTO_OBJECT_0 ) , index ) < = - 1 ) return - 1 ;
ret = pop ;
break ;
2015-06-03 17:24:11 +00:00
default :
stix - > errnum = STIX_EINTERN ;
2015-06-11 09:11:18 +00:00
goto oops ;
2015-06-03 17:24:11 +00:00
}
2015-05-25 17:10:49 +00:00
}
else
{
2015-07-10 14:06:07 +00:00
/* what is held in assignee is not an assignee any more.
* potentially it is a variable or object reference
* to be pused on to the stack */
2015-07-01 15:01:39 +00:00
assignee . ptr = & stix - > c - > mth . assignees . ptr [ assignee_offset ] ;
2015-07-10 14:06:07 +00:00
if ( compile_basic_expression ( stix , & assignee , & assignee_loc , assignee_dotted ) < = - 1 ) goto oops ;
2015-05-25 17:10:49 +00:00
}
}
else
{
2015-06-01 15:59:16 +00:00
assignee . len = 0 ;
2015-07-10 14:06:07 +00:00
if ( compile_basic_expression ( stix , STIX_NULL , STIX_NULL , 0 ) < = - 1 ) goto oops ;
2015-05-25 17:10:49 +00:00
}
2015-06-01 15:59:16 +00:00
stix - > c - > mth . assignees . len - = assignee . len ;
2015-06-11 09:11:18 +00:00
return ret ;
2015-05-25 17:10:49 +00:00
2015-06-01 15:59:16 +00:00
oops :
stix - > c - > mth . assignees . len - = assignee . len ;
2015-05-25 17:10:49 +00:00
return - 1 ;
}
2015-05-22 15:09:45 +00:00
2015-06-20 03:07:11 +00:00
static int compile_block_statement ( stix_t * stix )
{
/* compile_block_statement() is a simpler version of
* of compile_method_statement ( ) . it doesn ' t cater for
* popping the stack top */
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_RETURN )
2015-06-20 03:07:11 +00:00
{
/* handle the return statement */
GET_TOKEN ( stix ) ;
if ( compile_method_expression ( stix , 0 ) < = - 1 ) return - 1 ;
2015-06-29 13:52:40 +00:00
return emit_byte_instruction ( stix , BCODE_RETURN_STACKTOP ) ;
2015-06-20 03:07:11 +00:00
}
else
{
return compile_method_expression ( stix , 0 ) ;
}
}
2015-06-01 15:59:16 +00:00
static int compile_method_statement ( stix_t * stix )
2015-05-22 15:09:45 +00:00
{
2015-06-01 15:59:16 +00:00
/*
* method - statement : = method - return - statement | method - expression
* method - return - statement : = " ^ " method - expression
*/
2015-06-03 04:22:19 +00:00
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_RETURN )
2015-05-22 15:09:45 +00:00
{
2015-06-03 04:22:19 +00:00
/* handle the return statement */
2015-05-22 15:09:45 +00:00
GET_TOKEN ( stix ) ;
2015-06-11 09:11:18 +00:00
if ( compile_method_expression ( stix , 0 ) < = - 1 ) return - 1 ;
2015-06-29 13:52:40 +00:00
return emit_byte_instruction ( stix , BCODE_RETURN_STACKTOP ) ;
2015-05-22 15:09:45 +00:00
}
else
{
2015-06-11 09:11:18 +00:00
/* TODO: optimization. if expresssion is a literal, no push and pop are required */
int n ;
/* the second parameter to compile_method_expression() indicates
* that the stack top will eventually be popped off . the compiler
* can optimize some instruction sequencese . for example , two
* consecutive store and pop intructions can be transformed to
* a more specialized single pop - and - store instruction . */
n = compile_method_expression ( stix , 1 ) ;
if ( n < = - 1 ) return - 1 ;
2015-06-20 03:07:11 +00:00
/* if n is 1, no stack popping is required */
2016-02-12 16:23:26 +00:00
if ( n = = 0 )
{
return emit_byte_instruction ( stix , BCODE_POP_STACKTOP ) ;
}
return 0 ;
2015-05-22 15:09:45 +00:00
}
}
2015-05-28 15:20:27 +00:00
static int compile_method_statements ( stix_t * stix )
2015-05-22 15:09:45 +00:00
{
/*
2015-05-27 17:16:50 +00:00
* method - statements : = method - statement ( " . " | ( " . " method - statements ) ) *
2015-05-22 15:09:45 +00:00
*/
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) ! = STIX_IOTOK_EOF & &
TOKEN_TYPE ( stix ) ! = STIX_IOTOK_RBRACE )
2015-05-22 15:09:45 +00:00
{
do
{
2015-06-01 15:59:16 +00:00
if ( compile_method_statement ( stix ) < = - 1 ) return - 1 ;
2015-05-22 15:09:45 +00:00
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_PERIOD )
2015-05-22 15:09:45 +00:00
{
/* period after a statement */
GET_TOKEN ( stix ) ;
2015-06-03 17:24:11 +00:00
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_EOF | |
TOKEN_TYPE ( stix ) = = STIX_IOTOK_RBRACE ) break ;
2015-05-22 15:09:45 +00:00
}
2015-06-03 17:24:11 +00:00
else
2015-05-22 15:09:45 +00:00
{
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_EOF | |
TOKEN_TYPE ( stix ) = = STIX_IOTOK_RBRACE ) break ;
2015-06-11 09:11:18 +00:00
/* not a period, EOF, nor } */
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_PERIOD , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-06-11 09:11:18 +00:00
return - 1 ;
2015-05-22 15:09:45 +00:00
}
}
while ( 1 ) ;
}
2015-06-11 09:11:18 +00:00
/* arrange to return the receiver if execution reached
* the end of the method without explicit return */
2015-06-29 13:52:40 +00:00
return emit_byte_instruction ( stix , BCODE_RETURN_RECEIVER ) ;
2015-05-22 15:09:45 +00:00
}
2015-05-31 16:44:56 +00:00
static int add_compiled_method ( stix_t * stix )
{
2016-05-03 10:10:28 +00:00
stix_oop_char_t name ; /* selector */
2015-05-31 16:44:56 +00:00
stix_oop_method_t mth ; /* method */
2015-07-01 15:01:39 +00:00
# if defined(STIX_USE_OBJECT_TRAILER)
/* nothing extra */
# else
2015-06-06 07:24:35 +00:00
stix_oop_byte_t code ;
2015-07-01 15:01:39 +00:00
# endif
2015-12-17 16:11:10 +00:00
stix_oow_t tmp_count = 0 ;
stix_oow_t i ;
2015-06-09 12:14:18 +00:00
stix_ooi_t preamble_code , preamble_index ;
2015-05-31 16:44:56 +00:00
2016-05-03 10:10:28 +00:00
name = ( stix_oop_char_t ) stix_makesymbol ( stix , stix - > c - > mth . name . ptr , stix - > c - > mth . name . len ) ;
2015-05-31 18:43:37 +00:00
if ( ! name ) return - 1 ;
2016-05-03 10:10:28 +00:00
stix_pushtmp ( stix , ( stix_oop_t * ) & name ) ; tmp_count + + ;
2015-05-31 16:44:56 +00:00
2015-06-03 17:24:11 +00:00
/* The variadic data part passed to stix_instantiate() is not GC-safe */
2015-07-01 15:01:39 +00:00
# if defined(STIX_USE_OBJECT_TRAILER)
mth = ( stix_oop_method_t ) stix_instantiatewithtrailer ( stix , stix - > _method , stix - > c - > mth . literal_count , stix - > c - > mth . code . ptr , stix - > c - > mth . code . len ) ;
# else
2015-06-03 17:24:11 +00:00
mth = ( stix_oop_method_t ) stix_instantiate ( stix , stix - > _method , STIX_NULL , stix - > c - > mth . literal_count ) ;
2015-07-01 15:01:39 +00:00
# endif
2015-05-31 16:44:56 +00:00
if ( ! mth ) goto oops ;
2015-07-01 15:01:39 +00:00
2015-06-03 17:24:11 +00:00
for ( i = 0 ; i < stix - > c - > mth . literal_count ; i + + )
{
/* let's do the variadic data initialization here */
2015-06-04 18:34:37 +00:00
mth - > slot [ i ] = stix - > c - > mth . literals [ i ] ;
2015-06-03 17:24:11 +00:00
}
2015-05-31 16:44:56 +00:00
stix_pushtmp ( stix , ( stix_oop_t * ) & mth ) ; tmp_count + + ;
2015-07-01 15:01:39 +00:00
# if defined(STIX_USE_OBJECT_TRAILER)
/* do nothing */
# else
2015-06-06 07:24:35 +00:00
code = ( stix_oop_byte_t ) stix_instantiate ( stix , stix - > _byte_array , stix - > c - > mth . code . ptr , stix - > c - > mth . code . len ) ;
2015-05-31 16:44:56 +00:00
if ( ! code ) goto oops ;
2015-06-06 07:24:35 +00:00
stix_pushtmp ( stix , ( stix_oop_t * ) & code ) ; tmp_count + + ;
2015-07-01 15:01:39 +00:00
# endif
2015-05-31 16:44:56 +00:00
2015-06-09 12:14:18 +00:00
preamble_code = STIX_METHOD_PREAMBLE_NONE ;
preamble_index = 0 ;
2015-10-08 14:26:04 +00:00
if ( stix - > c - > mth . prim_type < = 0 )
2015-06-09 12:14:18 +00:00
{
2015-10-08 14:26:04 +00:00
/* no primitive is set */
2015-06-09 12:14:18 +00:00
if ( stix - > c - > mth . code . len < = 0 )
{
preamble_code = STIX_METHOD_PREAMBLE_RETURN_RECEIVER ;
}
else
{
2015-06-29 13:52:40 +00:00
if ( stix - > c - > mth . code . ptr [ 0 ] = = BCODE_RETURN_RECEIVER )
2015-06-09 12:14:18 +00:00
{
preamble_code = STIX_METHOD_PREAMBLE_RETURN_RECEIVER ;
}
2015-07-02 15:45:48 +00:00
else if ( stix - > c - > mth . code . len > 1 & & stix - > c - > mth . code . ptr [ 1 ] = = BCODE_RETURN_STACKTOP )
2015-06-09 12:14:18 +00:00
{
2015-07-02 14:59:52 +00:00
switch ( stix - > c - > mth . code . ptr [ 0 ] )
2015-06-09 12:14:18 +00:00
{
2015-07-02 14:59:52 +00:00
case BCODE_PUSH_RECEIVER :
preamble_code = STIX_METHOD_PREAMBLE_RETURN_RECEIVER ;
break ;
case BCODE_PUSH_NIL :
preamble_code = STIX_METHOD_PREAMBLE_RETURN_NIL ;
break ;
case BCODE_PUSH_TRUE :
preamble_code = STIX_METHOD_PREAMBLE_RETURN_TRUE ;
break ;
case BCODE_PUSH_FALSE :
preamble_code = STIX_METHOD_PREAMBLE_RETURN_FALSE ;
break ;
case BCODE_PUSH_NEGONE :
preamble_code = STIX_METHOD_PREAMBLE_RETURN_NEGINDEX ;
preamble_index = 1 ;
break ;
case BCODE_PUSH_ZERO :
preamble_code = STIX_METHOD_PREAMBLE_RETURN_INDEX ;
preamble_index = 0 ;
break ;
case BCODE_PUSH_ONE :
preamble_code = STIX_METHOD_PREAMBLE_RETURN_INDEX ;
preamble_index = 1 ;
break ;
case BCODE_PUSH_TWO :
preamble_code = STIX_METHOD_PREAMBLE_RETURN_INDEX ;
preamble_index = 2 ;
break ;
case BCODE_PUSH_INSTVAR_0 :
case BCODE_PUSH_INSTVAR_1 :
case BCODE_PUSH_INSTVAR_2 :
case BCODE_PUSH_INSTVAR_3 :
case BCODE_PUSH_INSTVAR_4 :
case BCODE_PUSH_INSTVAR_5 :
case BCODE_PUSH_INSTVAR_6 :
case BCODE_PUSH_INSTVAR_7 :
preamble_code = STIX_METHOD_PREAMBLE_RETURN_INSTVAR ;
preamble_index = stix - > c - > mth . code . ptr [ 0 ] & 0x7 ; /* low 3 bits */
break ;
2015-06-09 12:14:18 +00:00
}
2015-07-02 14:59:52 +00:00
}
2015-07-02 15:45:48 +00:00
else if ( stix - > c - > mth . code . len > STIX_BCODE_LONG_PARAM_SIZE + 1 & &
2015-07-02 14:59:52 +00:00
stix - > c - > mth . code . ptr [ STIX_BCODE_LONG_PARAM_SIZE + 1 ] = = BCODE_RETURN_STACKTOP )
{
int i ;
2015-07-02 15:45:48 +00:00
switch ( stix - > c - > mth . code . ptr [ 0 ] )
{
case BCODE_PUSH_INSTVAR_X :
preamble_code = STIX_METHOD_PREAMBLE_RETURN_INSTVAR ;
goto set_preamble_index ;
2015-07-02 14:59:52 +00:00
2015-07-02 15:45:48 +00:00
case BCODE_PUSH_INTLIT :
preamble_code = STIX_METHOD_PREAMBLE_RETURN_INDEX ;
goto set_preamble_index ;
2015-07-02 14:59:52 +00:00
2015-07-02 15:45:48 +00:00
case BCODE_PUSH_NEGINTLIT :
preamble_code = STIX_METHOD_PREAMBLE_RETURN_NEGINDEX ;
goto set_preamble_index ;
set_preamble_index :
2015-07-02 14:59:52 +00:00
preamble_index = 0 ;
2015-07-02 15:45:48 +00:00
for ( i = 1 ; i < = STIX_BCODE_LONG_PARAM_SIZE ; i + + )
{
preamble_index = ( preamble_index < < 8 ) | stix - > c - > mth . code . ptr [ i ] ;
}
2016-05-27 15:01:54 +00:00
if ( ! STIX_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE ( preamble_index ) )
2015-07-02 15:45:48 +00:00
{
/* the index got out of the range */
preamble_code = STIX_METHOD_PREAMBLE_NONE ;
preamble_index = 0 ;
}
2015-06-09 12:14:18 +00:00
}
}
}
}
2015-10-08 14:26:04 +00:00
else if ( stix - > c - > mth . prim_type = = 1 )
2015-06-09 12:14:18 +00:00
{
preamble_code = STIX_METHOD_PREAMBLE_PRIMITIVE ;
preamble_index = stix - > c - > mth . prim_no ;
}
2016-03-28 13:25:36 +00:00
else if ( stix - > c - > mth . prim_type = = 2 )
2015-10-08 14:26:04 +00:00
{
preamble_code = STIX_METHOD_PREAMBLE_NAMED_PRIMITIVE ;
preamble_index = stix - > c - > mth . prim_no ;
}
2016-06-22 03:23:14 +00:00
else if ( stix - > c - > mth . prim_type = = 3 )
2016-03-28 13:25:36 +00:00
{
preamble_code = STIX_METHOD_PREAMBLE_EXCEPTION ;
preamble_index = 0 ;
}
2016-06-22 03:23:14 +00:00
else
{
STIX_ASSERT ( stix - > c - > mth . prim_type = = 4 ) ;
preamble_code = STIX_METHOD_PREAMBLE_ENSURE ;
preamble_index = 0 ;
}
2015-06-09 12:14:18 +00:00
2016-05-27 15:01:54 +00:00
STIX_ASSERT ( STIX_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE ( preamble_index ) ) ;
2015-06-09 12:14:18 +00:00
2015-05-31 16:44:56 +00:00
mth - > owner = stix - > c - > cls . self_oop ;
2016-05-03 10:10:28 +00:00
mth - > name = name ;
2015-11-12 06:57:35 +00:00
mth - > preamble = STIX_SMOOI_TO_OOP ( STIX_METHOD_MAKE_PREAMBLE ( preamble_code , preamble_index ) ) ;
mth - > preamble_data [ 0 ] = STIX_SMOOI_TO_OOP ( 0 ) ;
mth - > preamble_data [ 1 ] = STIX_SMOOI_TO_OOP ( 0 ) ;
mth - > tmpr_count = STIX_SMOOI_TO_OOP ( stix - > c - > mth . tmpr_count ) ;
mth - > tmpr_nargs = STIX_SMOOI_TO_OOP ( stix - > c - > mth . tmpr_nargs ) ;
2015-07-01 15:01:39 +00:00
# if defined(STIX_USE_OBJECT_TRAILER)
/* do nothing */
# else
2015-05-31 16:44:56 +00:00
mth - > code = code ;
2015-07-01 15:01:39 +00:00
# endif
2015-06-01 15:59:16 +00:00
/*TODO: preserve source??? mth->text = stix->c->mth.text
the compiler must collect all source method string collected so far .
need to write code to collect string .
*/
2015-05-31 16:44:56 +00:00
2016-06-05 18:01:35 +00:00
# if defined(STIX_DEBUG_COMPILER)
stix_decode ( stix , mth , & stix - > c - > cls . fqn ) ;
# endif
2016-05-27 15:01:54 +00:00
2015-05-31 16:44:56 +00:00
stix_poptmps ( stix , tmp_count ) ; tmp_count = 0 ;
2016-05-03 10:10:28 +00:00
if ( ! stix_putatdic ( stix , stix - > c - > cls . mthdic_oop [ stix - > c - > mth . type ] , ( stix_oop_t ) name , ( stix_oop_t ) mth ) ) goto oops ;
2016-05-27 15:01:54 +00:00
2015-05-31 16:44:56 +00:00
return 0 ;
oops :
stix_poptmps ( stix , tmp_count ) ;
return - 1 ;
}
2015-06-01 15:59:16 +00:00
static int compile_method_definition ( stix_t * stix )
2015-05-20 15:24:37 +00:00
{
2015-05-21 17:07:55 +00:00
/* clear data required to compile a method */
2015-05-31 16:44:56 +00:00
stix - > c - > mth . type = MTH_INSTANCE ;
2015-06-01 15:59:16 +00:00
stix - > c - > mth . text . len = 0 ;
stix - > c - > mth . assignees . len = 0 ;
2015-06-03 17:24:11 +00:00
stix - > c - > mth . binsels . len = 0 ;
stix - > c - > mth . kwsels . len = 0 ;
2015-05-27 17:16:50 +00:00
stix - > c - > mth . name . len = 0 ;
2015-05-28 15:20:27 +00:00
STIX_MEMSET ( & stix - > c - > mth . name_loc , 0 , STIX_SIZEOF ( stix - > c - > mth . name_loc ) ) ;
2015-05-27 17:16:50 +00:00
stix - > c - > mth . tmprs . len = 0 ;
stix - > c - > mth . tmpr_count = 0 ;
stix - > c - > mth . tmpr_nargs = 0 ;
2015-05-31 16:44:56 +00:00
stix - > c - > mth . literal_count = 0 ;
2015-06-23 14:00:26 +00:00
stix - > c - > mth . balit_count = 0 ;
stix - > c - > mth . arlit_count = 0 ;
2015-10-08 14:26:04 +00:00
stix - > c - > mth . prim_type = 0 ;
stix - > c - > mth . prim_no = 0 ;
2015-06-30 14:47:39 +00:00
stix - > c - > mth . blk_depth = 0 ;
stix - > c - > mth . code . len = 0 ;
2015-05-27 17:16:50 +00:00
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_LPAREN )
2015-05-27 17:16:50 +00:00
{
/* process method modifiers */
GET_TOKEN ( stix ) ;
2015-06-03 17:24:11 +00:00
if ( is_token_symbol ( stix , VOCA_CLASS ) )
2015-05-27 17:16:50 +00:00
{
/* #method(#class) */
2015-05-31 16:44:56 +00:00
stix - > c - > mth . type = MTH_CLASS ;
2015-05-27 17:16:50 +00:00
GET_TOKEN ( stix ) ;
}
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) ! = STIX_IOTOK_RPAREN )
2015-05-27 17:16:50 +00:00
{
/* ) expected */
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_RPAREN , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-05-27 17:16:50 +00:00
return - 1 ;
}
2015-05-21 17:07:55 +00:00
2015-05-27 17:16:50 +00:00
GET_TOKEN ( stix ) ;
}
if ( compile_method_name ( stix ) < = - 1 ) return - 1 ;
2015-05-21 17:07:55 +00:00
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) ! = STIX_IOTOK_LBRACE )
2015-05-21 17:07:55 +00:00
{
/* { expected */
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_LBRACE , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-05-21 17:07:55 +00:00
return - 1 ;
}
GET_TOKEN ( stix ) ;
2015-05-28 15:20:27 +00:00
if ( compile_method_temporaries ( stix ) < = - 1 | |
compile_method_primitive ( stix ) < = - 1 | |
2015-05-31 16:44:56 +00:00
compile_method_statements ( stix ) < = - 1 ) return - 1 ;
2015-05-21 17:07:55 +00:00
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) ! = STIX_IOTOK_RBRACE )
2015-05-21 17:07:55 +00:00
{
/* } expected */
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_RBRACE , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-05-21 17:07:55 +00:00
return - 1 ;
}
GET_TOKEN ( stix ) ;
2015-05-31 16:44:56 +00:00
/* add a compiled method to the method dictionary */
if ( add_compiled_method ( stix ) < = - 1 ) return - 1 ;
2015-05-20 15:24:37 +00:00
return 0 ;
}
2015-05-26 16:31:47 +00:00
static int make_defined_class ( stix_t * stix )
{
/* this function make a class object with no functions/methods */
stix_oop_t tmp ;
stix_oow_t spec , self_spec ;
int just_made = 0 ;
2015-05-27 17:41:11 +00:00
spec = STIX_CLASS_SPEC_MAKE ( stix - > c - > cls . var_count [ VAR_INSTANCE ] ,
2015-05-27 17:16:50 +00:00
( ( stix - > c - > cls . flags & CLASS_INDEXED ) ? 1 : 0 ) ,
stix - > c - > cls . indexed_type ) ;
2015-06-04 18:34:37 +00:00
self_spec = STIX_CLASS_SELFSPEC_MAKE ( stix - > c - > cls . var_count [ VAR_CLASS ] ,
stix - > c - > cls . var_count [ VAR_CLASSINST ] ) ;
2015-05-26 16:31:47 +00:00
2015-05-27 17:16:50 +00:00
if ( stix - > c - > cls . self_oop )
2015-05-26 16:31:47 +00:00
{
2015-06-11 09:11:18 +00:00
/* this is an internally created class object being defined. */
2015-05-27 17:16:50 +00:00
STIX_ASSERT ( STIX_CLASSOF ( stix , stix - > c - > cls . self_oop ) = = stix - > _class ) ;
STIX_ASSERT ( STIX_OBJ_GET_FLAGS_KERNEL ( stix - > c - > cls . self_oop ) = = 1 ) ;
2015-05-26 16:31:47 +00:00
2015-11-12 06:57:35 +00:00
if ( spec ! = STIX_OOP_TO_SMOOI ( stix - > c - > cls . self_oop - > spec ) | |
self_spec ! = STIX_OOP_TO_SMOOI ( stix - > c - > cls . self_oop - > selfspec ) )
2015-05-26 16:31:47 +00:00
{
2015-05-27 17:41:11 +00:00
/* it conflicts with internal definition */
2015-07-13 15:35:52 +00:00
set_syntax_error ( stix , STIX_SYNERR_CLASSCONTRA , & stix - > c - > cls . fqn_loc , & stix - > c - > cls . name ) ;
2015-05-26 16:31:47 +00:00
return - 1 ;
}
}
else
{
/* the class variables and class instance variables are placed
* inside the class object after the fixed part . */
tmp = stix_instantiate ( stix , stix - > _class , STIX_NULL ,
2015-05-27 17:41:11 +00:00
stix - > c - > cls . var_count [ VAR_CLASSINST ] + stix - > c - > cls . var_count [ VAR_CLASS ] ) ;
2015-05-26 16:31:47 +00:00
if ( ! tmp ) return - 1 ;
2015-06-11 09:11:18 +00:00
2015-05-26 16:31:47 +00:00
just_made = 1 ;
2015-05-27 17:16:50 +00:00
stix - > c - > cls . self_oop = ( stix_oop_class_t ) tmp ;
2015-05-26 16:31:47 +00:00
2015-05-27 17:16:50 +00:00
STIX_ASSERT ( STIX_CLASSOF ( stix , stix - > c - > cls . self_oop ) = = stix - > _class ) ;
2015-05-26 16:31:47 +00:00
2015-11-12 06:57:35 +00:00
stix - > c - > cls . self_oop - > spec = STIX_SMOOI_TO_OOP ( spec ) ;
stix - > c - > cls . self_oop - > selfspec = STIX_SMOOI_TO_OOP ( self_spec ) ;
2015-05-26 16:31:47 +00:00
}
2015-05-31 16:44:56 +00:00
/* TODO: check if the current class definition conflicts with the superclass.
* if superclass is byte variable , the current class cannot be word variable or something else .
* TODO : TODO : TODO :
*/
2015-05-27 17:16:50 +00:00
STIX_OBJ_SET_FLAGS_KERNEL ( stix - > c - > cls . self_oop , 2 ) ;
2015-05-26 16:31:47 +00:00
2015-06-11 09:11:18 +00:00
stix - > c - > cls . self_oop - > superclass = stix - > c - > cls . super_oop ;
2015-05-31 16:44:56 +00:00
tmp = stix_makesymbol ( stix , stix - > c - > cls . name . ptr , stix - > c - > cls . name . len ) ;
2015-05-26 16:31:47 +00:00
if ( ! tmp ) return - 1 ;
2015-05-27 17:16:50 +00:00
stix - > c - > cls . self_oop - > name = ( stix_oop_char_t ) tmp ;
2015-05-26 16:31:47 +00:00
2016-08-29 06:10:02 +00:00
tmp = stix_makestring ( stix , stix - > c - > cls . vars [ VAR_INSTANCE ] . ptr , stix - > c - > cls . vars [ VAR_INSTANCE ] . len ) ;
2015-05-26 16:31:47 +00:00
if ( ! tmp ) return - 1 ;
2015-05-27 17:16:50 +00:00
stix - > c - > cls . self_oop - > instvars = ( stix_oop_char_t ) tmp ;
2015-05-26 16:31:47 +00:00
2016-08-29 06:10:02 +00:00
tmp = stix_makestring ( stix , stix - > c - > cls . vars [ VAR_CLASS ] . ptr , stix - > c - > cls . vars [ VAR_CLASS ] . len ) ;
2015-05-26 16:31:47 +00:00
if ( ! tmp ) return - 1 ;
2015-05-27 17:16:50 +00:00
stix - > c - > cls . self_oop - > classvars = ( stix_oop_char_t ) tmp ;
2015-05-26 16:31:47 +00:00
2016-08-29 06:10:02 +00:00
tmp = stix_makestring ( stix , stix - > c - > cls . vars [ VAR_CLASSINST ] . ptr , stix - > c - > cls . vars [ VAR_CLASSINST ] . len ) ;
2015-05-26 16:31:47 +00:00
if ( ! tmp ) return - 1 ;
2015-05-27 17:16:50 +00:00
stix - > c - > cls . self_oop - > classinstvars = ( stix_oop_char_t ) tmp ;
2015-05-26 16:31:47 +00:00
2015-07-26 14:38:34 +00:00
tmp = stix_makestring ( stix , stix - > c - > cls . pooldic . ptr , stix - > c - > cls . pooldic . len ) ;
if ( ! tmp ) return - 1 ;
stix - > c - > cls . self_oop - > pooldics = ( stix_oop_char_t ) tmp ;
2015-05-31 16:44:56 +00:00
/* TOOD: good dictionary size */
2015-06-04 18:34:37 +00:00
tmp = ( stix_oop_t ) stix_makedic ( stix , stix - > _method_dictionary , INSTANCE_METHOD_DICTIONARY_SIZE ) ;
2015-05-28 16:51:37 +00:00
if ( ! tmp ) return - 1 ;
2015-05-31 16:44:56 +00:00
stix - > c - > cls . mthdic_oop [ MTH_INSTANCE ] = ( stix_oop_set_t ) tmp ;
/* TOOD: good dictionary size */
2015-06-04 18:34:37 +00:00
tmp = ( stix_oop_t ) stix_makedic ( stix , stix - > _method_dictionary , CLASS_METHOD_DICTIONARY_SIZE ) ;
2015-05-31 16:44:56 +00:00
if ( ! tmp ) return - 1 ;
stix - > c - > cls . mthdic_oop [ MTH_CLASS ] = ( stix_oop_set_t ) tmp ;
2015-05-28 16:51:37 +00:00
/* TODO: initialize more fields??? whatelse. */
2015-05-26 16:31:47 +00:00
2015-05-31 16:44:56 +00:00
/* TODO: update the subclasses field of the superclass if it's not nil */
2015-05-26 16:31:47 +00:00
if ( just_made )
{
/* register the class to the system dictionary */
2015-07-13 15:35:52 +00:00
/*if (!stix_putatsysdic(stix, (stix_oop_t)stix->c->cls.self_oop->name, (stix_oop_t)stix->c->cls.self_oop)) return -1;*/
if ( ! stix_putatdic ( stix , stix - > c - > cls . ns_oop , ( stix_oop_t ) stix - > c - > cls . self_oop - > name , ( stix_oop_t ) stix - > c - > cls . self_oop ) ) return - 1 ;
}
return 0 ;
}
2015-07-06 13:27:49 +00:00
static int __compile_class_definition ( stix_t * stix , int extend )
2015-05-20 15:24:37 +00:00
{
2015-05-22 15:09:45 +00:00
/*
* class - definition : = # class class - modifier ? " { " class - body " } "
2015-05-27 17:16:50 +00:00
* class - modifier : = " ( " ( # byte | # character | # word | # pointer ) ? " ) "
* class - body : = variable - definition * method - definition *
2015-05-22 15:09:45 +00:00
*
* variable - definition : = ( # dcl | # declare ) variable - modifier ? variable - list " . "
2015-05-27 17:16:50 +00:00
* variable - modifier : = " ( " ( # class | # classinst ) ? " ) "
2015-05-22 15:09:45 +00:00
* variable - list : = identifier *
*
2015-05-27 17:16:50 +00:00
* method - definition : = ( # mth | # method ) method - modifier ? method - actual - definition
* method - modifier : = " ( " ( # class | # instance ) ? " ) "
* method - actual - definition : = method - name " { " method - tempraries ? method - primitive ? method - statements * " } "
2015-05-20 15:24:37 +00:00
*/
2015-05-26 16:31:47 +00:00
stix_oop_association_t ass ;
2015-05-15 14:55:12 +00:00
2016-08-29 07:39:09 +00:00
if ( ! extend & & TOKEN_TYPE ( stix ) = = STIX_IOTOK_LPAREN )
2015-05-20 15:24:37 +00:00
{
/* process class modifiers */
2015-05-25 17:10:49 +00:00
2015-05-27 17:16:50 +00:00
GET_TOKEN ( stix ) ;
2015-05-26 16:31:47 +00:00
2015-06-03 17:24:11 +00:00
if ( is_token_symbol ( stix , VOCA_BYTE ) )
2015-05-27 17:16:50 +00:00
{
/* #class(#byte) */
stix - > c - > cls . flags | = CLASS_INDEXED ;
stix - > c - > cls . indexed_type = STIX_OBJ_TYPE_BYTE ;
2015-05-20 15:24:37 +00:00
GET_TOKEN ( stix ) ;
2015-05-27 17:16:50 +00:00
}
2015-06-03 17:24:11 +00:00
else if ( is_token_symbol ( stix , VOCA_CHARACTER ) )
2015-05-27 17:16:50 +00:00
{
/* #class(#character) */
stix - > c - > cls . flags | = CLASS_INDEXED ;
stix - > c - > cls . indexed_type = STIX_OBJ_TYPE_CHAR ;
GET_TOKEN ( stix ) ;
}
2015-10-29 15:24:46 +00:00
else if ( is_token_symbol ( stix , VOCA_HALFWORD ) )
{
/* #class(#halfword) */
stix - > c - > cls . flags | = CLASS_INDEXED ;
stix - > c - > cls . indexed_type = STIX_OBJ_TYPE_HALFWORD ;
GET_TOKEN ( stix ) ;
}
2015-06-03 17:24:11 +00:00
else if ( is_token_symbol ( stix , VOCA_WORD ) )
2015-05-27 17:16:50 +00:00
{
/* #class(#word) */
stix - > c - > cls . flags | = CLASS_INDEXED ;
stix - > c - > cls . indexed_type = STIX_OBJ_TYPE_WORD ;
GET_TOKEN ( stix ) ;
}
2015-06-03 17:24:11 +00:00
else if ( is_token_symbol ( stix , VOCA_POINTER ) )
2015-05-27 17:16:50 +00:00
{
/* #class(#pointer) */
stix - > c - > cls . flags | = CLASS_INDEXED ;
stix - > c - > cls . indexed_type = STIX_OBJ_TYPE_OOP ;
GET_TOKEN ( stix ) ;
}
2015-11-17 14:13:59 +00:00
else if ( is_token_symbol ( stix , VOCA_LIWORD ) )
{
/* #class(#biatom) */
stix - > c - > cls . flags | = CLASS_INDEXED ;
stix - > c - > cls . indexed_type = STIX_OBJ_TYPE_LIWORD ;
GET_TOKEN ( stix ) ;
}
2015-05-20 15:24:37 +00:00
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) ! = STIX_IOTOK_RPAREN )
2015-05-20 15:24:37 +00:00
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_RPAREN , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-05-20 15:24:37 +00:00
return - 1 ;
}
GET_TOKEN ( stix ) ;
}
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) ! = STIX_IOTOK_IDENT & &
TOKEN_TYPE ( stix ) ! = STIX_IOTOK_IDENT_DOTTED )
2015-05-15 14:55:12 +00:00
{
/* class name expected. */
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_IDENT , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-05-20 15:24:37 +00:00
return - 1 ;
}
2015-05-25 17:10:49 +00:00
/* copy the class name */
2016-08-29 07:39:09 +00:00
if ( set_class_fqn ( stix , TOKEN_NAME ( stix ) ) < = - 1 ) return - 1 ;
2015-07-13 15:35:52 +00:00
stix - > c - > cls . fqn_loc = stix - > c - > tok . loc ;
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_IDENT_DOTTED )
2015-07-13 15:35:52 +00:00
{
2015-07-15 08:39:18 +00:00
if ( preprocess_dotted_name ( stix , extend , 0 , & stix - > c - > cls . fqn , & stix - > c - > cls . fqn_loc , & stix - > c - > cls . name , & stix - > c - > cls . ns_oop ) < = - 1 ) return - 1 ;
2015-07-13 15:35:52 +00:00
}
else
{
stix - > c - > cls . ns_oop = stix - > sysdic ;
}
2015-05-25 17:10:49 +00:00
GET_TOKEN ( stix ) ;
2015-05-20 15:24:37 +00:00
2015-07-06 13:27:49 +00:00
if ( extend )
{
/* extending class */
STIX_ASSERT ( stix - > c - > cls . flags = = 0 ) ;
2015-07-13 15:35:52 +00:00
/*ass = stix_lookupsysdic(stix, &stix->c->cls.name);*/
ass = stix_lookupdic ( stix , stix - > c - > cls . ns_oop , & stix - > c - > cls . name ) ;
2015-07-06 13:27:49 +00:00
if ( ass & &
STIX_CLASSOF ( stix , ass - > value ) = = stix - > _class & &
STIX_OBJ_GET_FLAGS_KERNEL ( ass - > value ) ! = 1 )
{
/* the value must be a class object.
* and it must be either a user - defined ( 0 ) or
* completed kernel built - in ( 2 ) .
* an incomplete kernel built - in class object ( 1 ) can not be
* extended */
stix - > c - > cls . self_oop = ( stix_oop_class_t ) ass - > value ;
}
else
{
/* only an existing class can be extended. */
2015-07-13 15:35:52 +00:00
set_syntax_error ( stix , STIX_SYNERR_CLASSUNDEF , & stix - > c - > cls . fqn_loc , & stix - > c - > cls . name ) ;
2015-07-06 13:27:49 +00:00
return - 1 ;
}
stix - > c - > cls . super_oop = stix - > c - > cls . self_oop - > superclass ;
STIX_ASSERT ( ( stix_oop_t ) stix - > c - > cls . super_oop = = stix - > _nil | |
STIX_CLASSOF ( stix , stix - > c - > cls . super_oop ) = = stix - > _class ) ;
}
else
2015-05-20 15:24:37 +00:00
{
2015-05-28 16:51:37 +00:00
int super_is_nil = 0 ;
2016-06-05 18:01:35 +00:00
STIX_INFO2 ( stix , " Defining a class %.*S \n " , stix - > c - > cls . fqn . len , stix - > c - > cls . fqn . ptr ) ;
2016-06-03 16:16:23 +00:00
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_LPAREN )
2015-07-06 13:27:49 +00:00
{
/* superclass is specified. new class defintion.
* for example , # class Class ( Stix )
*/
GET_TOKEN ( stix ) ; /* read superclass name */
2015-05-25 17:10:49 +00:00
2015-07-06 13:27:49 +00:00
/* TODO: multiple inheritance */
2015-05-20 15:52:45 +00:00
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_NIL )
2015-07-06 13:27:49 +00:00
{
super_is_nil = 1 ;
}
2016-08-29 07:39:09 +00:00
else if ( TOKEN_TYPE ( stix ) ! = STIX_IOTOK_IDENT & &
TOKEN_TYPE ( stix ) ! = STIX_IOTOK_IDENT_DOTTED )
2015-07-06 13:27:49 +00:00
{
/* superclass name expected */
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_IDENT , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-07-06 13:27:49 +00:00
return - 1 ;
}
2015-05-20 15:52:45 +00:00
2016-08-29 07:39:09 +00:00
if ( set_superclass_fqn ( stix , TOKEN_NAME ( stix ) ) < = - 1 ) return - 1 ;
2015-07-13 15:35:52 +00:00
stix - > c - > cls . superfqn_loc = stix - > c - > tok . loc ;
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_IDENT_DOTTED )
2015-07-13 15:35:52 +00:00
{
2015-07-15 08:39:18 +00:00
if ( preprocess_dotted_name ( stix , 1 , 0 , & stix - > c - > cls . superfqn , & stix - > c - > cls . superfqn_loc , & stix - > c - > cls . supername , & stix - > c - > cls . superns_oop ) < = - 1 ) return - 1 ;
2015-07-13 15:35:52 +00:00
}
else
{
/* if no fully qualified name is specified for the super class name,
* the name is searched in the name space that the class being defined
* belongs to first and in the ' stix - > sysdic ' . */
stix - > c - > cls . superns_oop = stix - > c - > cls . ns_oop ;
}
2015-05-20 15:52:45 +00:00
2015-07-06 13:27:49 +00:00
GET_TOKEN ( stix ) ;
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) ! = STIX_IOTOK_RPAREN )
2015-07-06 13:27:49 +00:00
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_RPAREN , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-07-06 13:27:49 +00:00
return - 1 ;
}
2015-05-25 17:10:49 +00:00
2015-07-06 13:27:49 +00:00
GET_TOKEN ( stix ) ;
}
else
2015-05-20 15:52:45 +00:00
{
2015-07-06 13:27:49 +00:00
super_is_nil = 1 ;
2015-05-20 15:52:45 +00:00
}
2015-07-13 15:35:52 +00:00
/*ass = stix_lookupsysdic(stix, &stix->c->cls.name);*/
ass = stix_lookupdic ( stix , stix - > c - > cls . ns_oop , & stix - > c - > cls . name ) ;
2015-05-26 16:31:47 +00:00
if ( ass )
2015-05-25 17:10:49 +00:00
{
2015-05-26 16:31:47 +00:00
if ( STIX_CLASSOF ( stix , ass - > value ) ! = stix - > _class | |
STIX_OBJ_GET_FLAGS_KERNEL ( ass - > value ) > 1 )
2015-05-25 17:10:49 +00:00
{
/* the object found with the name is not a class object
2015-05-26 16:31:47 +00:00
* or the the class object found is a fully defined kernel
2015-05-25 17:10:49 +00:00
* class object */
2015-07-13 15:35:52 +00:00
set_syntax_error ( stix , STIX_SYNERR_CLASSDUP , & stix - > c - > cls . fqn_loc , & stix - > c - > cls . name ) ;
2015-05-25 17:10:49 +00:00
return - 1 ;
}
2015-07-13 15:35:52 +00:00
2015-05-27 17:16:50 +00:00
stix - > c - > cls . self_oop = ( stix_oop_class_t ) ass - > value ;
2015-05-26 16:31:47 +00:00
}
else
{
/* no class of such a name is found. it's a new definition,
* which is normal for most new classes . */
2015-05-27 17:16:50 +00:00
STIX_ASSERT ( stix - > c - > cls . self_oop = = STIX_NULL ) ;
2015-05-25 17:10:49 +00:00
}
if ( super_is_nil )
{
2015-05-27 17:16:50 +00:00
stix - > c - > cls . super_oop = stix - > _nil ;
2015-05-25 17:10:49 +00:00
}
else
{
2015-07-13 15:35:52 +00:00
/* ass = stix_lookupsysdic(stix, &stix->c->cls.supername); */
ass = stix_lookupdic ( stix , stix - > c - > cls . superns_oop , & stix - > c - > cls . supername ) ;
if ( ! ass & & stix - > c - > cls . superns_oop ! = stix - > sysdic )
ass = stix_lookupdic ( stix , stix - > sysdic , & stix - > c - > cls . supername ) ;
2015-05-26 16:31:47 +00:00
if ( ass & &
STIX_CLASSOF ( stix , ass - > value ) = = stix - > _class & &
STIX_OBJ_GET_FLAGS_KERNEL ( ass - > value ) ! = 1 )
{
/* the value found must be a class and it must not be
* an incomplete internal class object */
2015-05-27 17:16:50 +00:00
stix - > c - > cls . super_oop = ass - > value ;
2015-05-26 16:31:47 +00:00
}
else
2015-05-25 17:10:49 +00:00
{
/* there is no object with such a name. or,
* the object found with the name is not a class object . or ,
* the class object found is a internally defined kernel
* class object . */
2015-07-13 15:35:52 +00:00
set_syntax_error ( stix , STIX_SYNERR_CLASSUNDEF , & stix - > c - > cls . superfqn_loc , & stix - > c - > cls . superfqn ) ;
2015-05-25 17:10:49 +00:00
return - 1 ;
}
}
2015-07-06 13:27:49 +00:00
2015-05-20 15:24:37 +00:00
}
2015-05-20 15:52:45 +00:00
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) ! = STIX_IOTOK_LBRACE )
2015-05-20 15:24:37 +00:00
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_LBRACE , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-05-15 14:55:12 +00:00
return - 1 ;
}
2015-05-27 17:16:50 +00:00
if ( stix - > c - > cls . super_oop ! = stix - > _nil )
2015-05-26 16:31:47 +00:00
{
/* adjust the instance variable count and the class instance variable
* count to include that of a superclass */
stix_oop_class_t c ;
stix_oow_t spec , self_spec ;
2015-05-27 17:16:50 +00:00
c = ( stix_oop_class_t ) stix - > c - > cls . super_oop ;
2015-11-12 06:57:35 +00:00
spec = STIX_OOP_TO_SMOOI ( c - > spec ) ;
self_spec = STIX_OOP_TO_SMOOI ( c - > selfspec ) ;
2015-05-27 17:41:11 +00:00
stix - > c - > cls . var_count [ VAR_INSTANCE ] = STIX_CLASS_SPEC_NAMED_INSTVAR ( spec ) ;
stix - > c - > cls . var_count [ VAR_CLASSINST ] = STIX_CLASS_SELFSPEC_CLASSINSTVAR ( self_spec ) ;
2015-05-26 16:31:47 +00:00
}
2015-05-20 15:52:45 +00:00
GET_TOKEN ( stix ) ;
2015-07-06 13:27:49 +00:00
if ( extend )
2015-05-26 16:31:47 +00:00
{
2016-08-29 06:10:02 +00:00
stix_oop_char_t pds ;
2015-05-27 17:16:50 +00:00
/* when a class is extended, a new variable cannot be added */
2015-06-03 17:24:11 +00:00
if ( is_token_symbol ( stix , VOCA_DCL ) | | is_token_symbol ( stix , VOCA_DECLARE ) )
2015-05-20 15:24:37 +00:00
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_DCLBANNED , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-05-26 16:31:47 +00:00
return - 1 ;
2015-05-20 15:24:37 +00:00
}
2015-05-31 16:44:56 +00:00
/* use the method dictionary of an existing class object */
2015-06-06 07:24:35 +00:00
stix - > c - > cls . mthdic_oop [ MTH_INSTANCE ] = stix - > c - > cls . self_oop - > mthdic [ STIX_CLASS_MTHDIC_INSTANCE ] ;
stix - > c - > cls . mthdic_oop [ MTH_CLASS ] = stix - > c - > cls . self_oop - > mthdic [ STIX_CLASS_MTHDIC_CLASS ] ;
2016-08-29 06:10:02 +00:00
/* load the pooldic definition from the existing class object */
pds = stix - > c - > cls . self_oop - > pooldics ;
if ( ( stix_oop_t ) pds ! = stix - > _nil )
{
stix_ooch_t * ptr , * end ;
STIX_ASSERT ( STIX_CLASSOF ( stix , pds ) = = stix - > _string ) ;
ptr = pds - > slot ;
end = pds - > slot + STIX_OBJ_GET_SIZE ( pds ) ;
/* this loop handles the pooldics string as if it's a pooldic import.
* see compile_class_level_variables ( ) for mostly identical code except token handling */
do
{
stix_oocs_t last , tok ;
stix_ioloc_t loc ;
int dotted = 0 ;
stix_oop_set_t ns_oop ;
while ( ptr < end & & is_spacechar ( * ptr ) ) ptr + + ;
if ( ptr > = end ) break ;
STIX_MEMSET ( & loc , 0 , STIX_SIZEOF ( loc ) ) ; /* fake location */
tok . ptr = ptr ;
while ( ptr < end & & ! is_spacechar ( * ptr ) )
{
if ( * ptr = = ' . ' ) dotted = 1 ;
ptr + + ;
}
tok . len = ptr - tok . ptr ;
STIX_ASSERT ( tok . len > 0 ) ;
if ( dotted )
{
if ( preprocess_dotted_name ( stix , 0 , 0 , & tok , & loc , & last , & ns_oop ) < = - 1 ) return - 1 ;
}
else
{
last = tok ;
/* it falls back to the name space of the class */
ns_oop = stix - > c - > cls . ns_oop ;
}
if ( import_pool_dictionary ( stix , ns_oop , & last , & tok , & loc ) < = - 1 ) return - 1 ;
}
while ( 1 ) ;
}
2015-05-26 16:31:47 +00:00
}
else
{
/* a new class including an internally defined class object */
2015-06-03 17:24:11 +00:00
while ( is_token_symbol ( stix , VOCA_DCL ) | | is_token_symbol ( stix , VOCA_DECLARE ) )
2015-05-20 15:24:37 +00:00
{
2015-05-26 16:31:47 +00:00
/* variable definition. #dcl or #declare */
GET_TOKEN ( stix ) ;
if ( compile_class_level_variables ( stix ) < = - 1 ) return - 1 ;
2015-05-20 15:24:37 +00:00
}
2015-05-26 16:31:47 +00:00
if ( make_defined_class ( stix ) < = - 1 ) return - 1 ;
2015-05-20 15:24:37 +00:00
}
2015-06-03 17:24:11 +00:00
while ( is_token_symbol ( stix , VOCA_MTH ) | | is_token_symbol ( stix , VOCA_METHOD ) )
2015-05-26 16:31:47 +00:00
{
2015-05-27 17:16:50 +00:00
/* method definition. #mth or #method */
2015-05-26 16:31:47 +00:00
GET_TOKEN ( stix ) ;
2015-06-01 15:59:16 +00:00
if ( compile_method_definition ( stix ) < = - 1 ) return - 1 ;
2015-05-26 16:31:47 +00:00
}
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) ! = STIX_IOTOK_RBRACE )
2015-05-20 15:24:37 +00:00
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_RBRACE , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-05-20 15:24:37 +00:00
return - 1 ;
}
2015-07-06 13:27:49 +00:00
if ( ! extend )
2015-05-31 16:44:56 +00:00
{
/* TODO: anything else to set? */
2015-06-06 07:24:35 +00:00
stix - > c - > cls . self_oop - > mthdic [ STIX_CLASS_MTHDIC_INSTANCE ] = stix - > c - > cls . mthdic_oop [ MTH_INSTANCE ] ;
stix - > c - > cls . self_oop - > mthdic [ STIX_CLASS_MTHDIC_CLASS ] = stix - > c - > cls . mthdic_oop [ MTH_CLASS ] ;
2015-05-31 16:44:56 +00:00
}
2015-05-20 15:24:37 +00:00
GET_TOKEN ( stix ) ;
return 0 ;
2015-05-25 17:10:49 +00:00
}
2015-05-20 15:24:37 +00:00
2015-07-06 13:27:49 +00:00
static int compile_class_definition ( stix_t * stix , int extend )
2015-05-25 17:10:49 +00:00
{
int n ;
2015-12-17 16:11:10 +00:00
stix_oow_t i ;
2015-05-15 14:55:12 +00:00
2015-05-25 17:10:49 +00:00
/* reset the structure to hold information about a class to be compiled */
2015-05-27 17:16:50 +00:00
stix - > c - > cls . flags = 0 ;
2015-06-21 16:22:50 +00:00
stix - > c - > cls . indexed_type = STIX_OBJ_TYPE_OOP ;
2015-05-28 15:20:27 +00:00
2015-05-27 17:16:50 +00:00
stix - > c - > cls . name . len = 0 ;
stix - > c - > cls . supername . len = 0 ;
2015-07-13 15:35:52 +00:00
STIX_MEMSET ( & stix - > c - > cls . fqn_loc , 0 , STIX_SIZEOF ( stix - > c - > cls . fqn_loc ) ) ;
STIX_MEMSET ( & stix - > c - > cls . superfqn_loc , 0 , STIX_SIZEOF ( stix - > c - > cls . superfqn_loc ) ) ;
2015-05-28 15:20:27 +00:00
2015-06-21 14:45:45 +00:00
STIX_ASSERT ( STIX_COUNTOF ( stix - > c - > cls . var_count ) = = STIX_COUNTOF ( stix - > c - > cls . vars ) ) ;
2015-05-27 17:16:50 +00:00
for ( i = 0 ; i < STIX_COUNTOF ( stix - > c - > cls . var_count ) ; i + + )
2015-06-21 14:45:45 +00:00
{
2015-05-27 17:16:50 +00:00
stix - > c - > cls . var_count [ i ] = 0 ;
2015-06-21 14:45:45 +00:00
stix - > c - > cls . vars [ i ] . len = 0 ;
}
2015-05-15 14:55:12 +00:00
2015-07-26 14:38:34 +00:00
stix - > c - > cls . pooldic_count = 0 ;
stix - > c - > cls . pooldic . len = 0 ;
2015-05-27 17:16:50 +00:00
stix - > c - > cls . self_oop = STIX_NULL ;
stix - > c - > cls . super_oop = STIX_NULL ;
2015-05-31 16:44:56 +00:00
stix - > c - > cls . mthdic_oop [ MTH_INSTANCE ] = STIX_NULL ;
stix - > c - > cls . mthdic_oop [ MTH_CLASS ] = STIX_NULL ;
2015-07-13 15:35:52 +00:00
stix - > c - > cls . ns_oop = STIX_NULL ;
stix - > c - > cls . superns_oop = STIX_NULL ;
2015-05-31 16:44:56 +00:00
stix - > c - > mth . literal_count = 0 ;
2015-06-23 14:00:26 +00:00
stix - > c - > mth . balit_count = 0 ;
stix - > c - > mth . arlit_count = 0 ;
2015-06-21 14:45:45 +00:00
2015-05-25 17:10:49 +00:00
/* do main compilation work */
2015-07-06 13:27:49 +00:00
n = __compile_class_definition ( stix , extend ) ;
2015-05-15 14:55:12 +00:00
2015-05-31 16:44:56 +00:00
/* reset these oops plus literal pointers not to confuse gc_compiler() */
2015-05-27 17:16:50 +00:00
stix - > c - > cls . self_oop = STIX_NULL ;
stix - > c - > cls . super_oop = STIX_NULL ;
2015-05-31 16:44:56 +00:00
stix - > c - > cls . mthdic_oop [ MTH_INSTANCE ] = STIX_NULL ;
stix - > c - > cls . mthdic_oop [ MTH_CLASS ] = STIX_NULL ;
2015-07-13 15:35:52 +00:00
stix - > c - > cls . ns_oop = STIX_NULL ;
stix - > c - > cls . superns_oop = STIX_NULL ;
2015-05-31 16:44:56 +00:00
stix - > c - > mth . literal_count = 0 ;
2015-06-23 14:00:26 +00:00
stix - > c - > mth . balit_count = 0 ;
stix - > c - > mth . arlit_count = 0 ;
2015-05-15 14:55:12 +00:00
2015-07-26 14:38:34 +00:00
stix - > c - > cls . pooldic_count = 0 ;
2015-05-25 17:10:49 +00:00
return n ;
2015-05-20 15:24:37 +00:00
}
2015-07-14 13:35:18 +00:00
static int __compile_pooldic_definition ( stix_t * stix )
{
stix_oop_t lit ;
stix_ooi_t tally ;
2015-12-17 16:11:10 +00:00
stix_oow_t i ;
2015-07-14 13:35:18 +00:00
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) ! = STIX_IOTOK_IDENT & &
TOKEN_TYPE ( stix ) ! = STIX_IOTOK_IDENT_DOTTED )
2015-07-14 13:35:18 +00:00
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_IDENT , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-07-14 13:35:18 +00:00
return - 1 ;
}
/* [NOTE]
* reuse stix - > c - > cls . fqn and related fields are reused
* to store the pool dictionary name */
2016-08-29 07:39:09 +00:00
if ( set_class_fqn ( stix , TOKEN_NAME ( stix ) ) < = - 1 ) return - 1 ;
2015-07-14 13:35:18 +00:00
stix - > c - > cls . fqn_loc = stix - > c - > tok . loc ;
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_IDENT_DOTTED )
2015-07-14 13:35:18 +00:00
{
2015-07-15 08:39:18 +00:00
if ( preprocess_dotted_name ( stix , 0 , 0 , & stix - > c - > cls . fqn , & stix - > c - > cls . fqn_loc , & stix - > c - > cls . name , & stix - > c - > cls . ns_oop ) < = - 1 ) return - 1 ;
2015-07-14 13:35:18 +00:00
}
else
{
stix - > c - > cls . ns_oop = stix - > sysdic ;
}
if ( stix_lookupdic ( stix , stix - > c - > cls . ns_oop , & stix - > c - > cls . name ) )
{
/* a conflicting entry has been found */
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_POOLDICDUP , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-07-14 13:35:18 +00:00
return - 1 ;
}
GET_TOKEN ( stix ) ;
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) ! = STIX_IOTOK_LBRACE )
2015-07-14 13:35:18 +00:00
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_LBRACE , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-07-14 13:35:18 +00:00
return - 1 ;
}
2016-06-05 18:01:35 +00:00
STIX_INFO2 ( stix , " Defining a pool dictionary %.*S \n " , stix - > c - > cls . fqn . len , stix - > c - > cls . fqn . ptr ) ;
2015-07-15 08:39:18 +00:00
2015-07-14 13:35:18 +00:00
GET_TOKEN ( stix ) ;
2016-08-29 07:39:09 +00:00
while ( TOKEN_TYPE ( stix ) = = STIX_IOTOK_SYMLIT )
2015-07-14 13:35:18 +00:00
{
lit = stix_makesymbol ( stix , stix - > c - > tok . name . ptr , stix - > c - > tok . name . len ) ;
2016-01-29 04:04:39 +00:00
if ( ! lit | | add_to_array_literal_buffer ( stix , lit ) < = - 1 ) return - 1 ;
2015-07-14 13:35:18 +00:00
GET_TOKEN ( stix ) ;
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) ! = STIX_IOTOK_ASSIGN )
2015-07-14 13:35:18 +00:00
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_ASSIGN , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-07-14 13:35:18 +00:00
return - 1 ;
}
GET_TOKEN ( stix ) ;
2016-09-06 16:06:22 +00:00
switch ( TOKEN_TYPE ( stix ) )
2015-07-14 13:35:18 +00:00
{
case STIX_IOTOK_NIL :
lit = stix - > _nil ;
2015-07-15 08:39:18 +00:00
goto add_literal ;
2015-07-14 13:35:18 +00:00
case STIX_IOTOK_TRUE :
lit = stix - > _true ;
2015-07-15 08:39:18 +00:00
goto add_literal ;
2015-07-14 13:35:18 +00:00
case STIX_IOTOK_FALSE :
lit = stix - > _false ;
2015-07-15 08:39:18 +00:00
goto add_literal ;
2015-07-14 13:35:18 +00:00
case STIX_IOTOK_CHARLIT :
STIX_ASSERT ( stix - > c - > tok . name . len = = 1 ) ;
2015-11-20 09:05:55 +00:00
lit = STIX_CHAR_TO_OOP ( stix - > c - > tok . name . ptr [ 0 ] ) ;
2015-07-15 08:39:18 +00:00
goto add_literal ;
2015-07-14 13:35:18 +00:00
case STIX_IOTOK_STRLIT :
lit = stix_instantiate ( stix , stix - > _string , stix - > c - > tok . name . ptr , stix - > c - > tok . name . len ) ;
if ( ! lit ) return - 1 ;
2015-07-15 08:39:18 +00:00
goto add_literal ;
2015-07-14 13:35:18 +00:00
case STIX_IOTOK_SYMLIT :
lit = stix_makesymbol ( stix , stix - > c - > tok . name . ptr , stix - > c - > tok . name . len ) ;
if ( ! lit ) return - 1 ;
2015-07-15 08:39:18 +00:00
goto add_literal ;
2015-07-14 13:35:18 +00:00
case STIX_IOTOK_NUMLIT :
case STIX_IOTOK_RADNUMLIT :
2016-08-29 07:39:09 +00:00
lit = string_to_num ( stix , TOKEN_NAME ( stix ) , TOKEN_TYPE ( stix ) = = STIX_IOTOK_RADNUMLIT ) ;
2015-11-12 06:57:35 +00:00
if ( ! lit ) return - 1 ;
2015-07-15 08:39:18 +00:00
goto add_literal ;
2016-09-06 16:06:22 +00:00
case STIX_IOTOK_BAPAREN : /* #[ - byte array parenthesis */
2015-07-15 08:39:18 +00:00
if ( read_byte_array_literal ( stix , & lit ) < = - 1 ) return - 1 ;
goto add_literal ;
2015-07-14 13:35:18 +00:00
2016-09-06 16:06:22 +00:00
case STIX_IOTOK_ARPAREN : /* #( - array parenthesis */
2015-07-15 08:39:18 +00:00
if ( read_array_literal ( stix , & lit ) < = - 1 ) return - 1 ;
goto add_literal ;
add_literal :
/*
* for this definition , # pooldic MyPoolDic { # a : = 10. # b : = 20 } ,
* arlit_buffer contains ( # a 10 # b 20 ) when the ' while ' loop is over . */
2016-01-29 04:04:39 +00:00
if ( add_to_array_literal_buffer ( stix , lit ) < = - 1 ) return - 1 ;
2015-07-14 13:35:18 +00:00
GET_TOKEN ( stix ) ;
break ;
2015-07-15 08:39:18 +00:00
default :
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_LITERAL , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-07-15 08:39:18 +00:00
return - 1 ;
2015-07-14 13:35:18 +00:00
}
2016-08-29 07:39:09 +00:00
/*if (TOKEN_TYPE(stix) == STIX_IOTOK_RBRACE) goto done;
else */ if ( TOKEN_TYPE ( stix ) ! = STIX_IOTOK_PERIOD )
2015-07-14 13:35:18 +00:00
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_PERIOD , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-07-14 13:35:18 +00:00
return - 1 ;
}
GET_TOKEN ( stix ) ;
}
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) ! = STIX_IOTOK_RBRACE )
2015-07-14 13:35:18 +00:00
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_RBRACE , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-07-14 13:35:18 +00:00
return - 1 ;
}
/*done:*/
GET_TOKEN ( stix ) ;
tally = stix - > c - > mth . arlit_count / 2 ;
/*TODO: tally and arlit_count range check */
2015-11-12 06:57:35 +00:00
/*if (!STIX_IN_SMOOI_RANGE(tally)) ERROR??*/
2015-07-14 13:35:18 +00:00
stix - > c - > cls . mthdic_oop [ 0 ] = stix_makedic ( stix , stix - > _pool_dictionary , STIX_ALIGN ( tally + 10 , POOL_DICTIONARY_SIZE_ALIGN ) ) ;
if ( ! stix - > c - > cls . mthdic_oop [ 0 ] ) return - 1 ;
for ( i = 0 ; i < stix - > c - > mth . arlit_count ; i + = 2 )
{
/* TODO: handle duplicate keys? */
if ( ! stix_putatdic ( stix , stix - > c - > cls . mthdic_oop [ 0 ] , stix - > c - > mth . arlit [ i ] , stix - > c - > mth . arlit [ i + 1 ] ) ) return - 1 ;
}
/* eveything seems ok. register the pool dictionary to the main
* system dictionary or to the name space it belongs to */
lit = stix_makesymbol ( stix , stix - > c - > cls . name . ptr , stix - > c - > cls . name . len ) ;
if ( ! lit | | ! stix_putatdic ( stix , stix - > c - > cls . ns_oop , lit , ( stix_oop_t ) stix - > c - > cls . mthdic_oop [ 0 ] ) ) return - 1 ;
return 0 ;
}
static int compile_pooldic_definition ( stix_t * stix )
{
int n ;
/* reset the structure to hold information about a pool dictionary to be compiled.
* i ' ll be reusing some fields reserved for compling a class */
stix - > c - > cls . name . len = 0 ;
STIX_MEMSET ( & stix - > c - > cls . fqn_loc , 0 , STIX_SIZEOF ( stix - > c - > cls . fqn_loc ) ) ;
stix - > c - > cls . mthdic_oop [ 0 ] = STIX_NULL ;
stix - > c - > cls . ns_oop = STIX_NULL ;
stix - > c - > mth . balit_count = 0 ;
stix - > c - > mth . arlit_count = 0 ;
n = __compile_pooldic_definition ( stix ) ;
/* reset these oops plus literal pointers not to confuse gc_compiler() */
stix - > c - > cls . mthdic_oop [ 0 ] = STIX_NULL ;
stix - > c - > cls . ns_oop = STIX_NULL ;
stix - > c - > mth . balit_count = 0 ;
stix - > c - > mth . arlit_count = 0 ;
2015-07-15 08:39:18 +00:00
2015-07-14 13:35:18 +00:00
return n ;
}
2015-05-19 15:16:18 +00:00
static int compile_stream ( stix_t * stix )
2015-05-15 14:55:12 +00:00
{
2015-05-19 15:16:18 +00:00
GET_CHAR ( stix ) ;
GET_TOKEN ( stix ) ;
2016-08-29 07:39:09 +00:00
while ( TOKEN_TYPE ( stix ) ! = STIX_IOTOK_EOF )
2015-05-19 15:16:18 +00:00
{
2015-06-03 17:24:11 +00:00
if ( is_token_symbol ( stix , VOCA_INCLUDE ) )
2015-05-15 14:55:12 +00:00
{
2015-05-20 14:27:47 +00:00
/* #include 'xxxx' */
2015-05-19 15:16:18 +00:00
GET_TOKEN ( stix ) ;
2016-08-29 07:39:09 +00:00
if ( TOKEN_TYPE ( stix ) ! = STIX_IOTOK_STRLIT )
2015-05-20 14:27:47 +00:00
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_STRING , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-05-20 14:27:47 +00:00
return - 1 ;
}
if ( begin_include ( stix ) < = - 1 ) return - 1 ;
2015-05-15 14:55:12 +00:00
}
2015-06-03 17:24:11 +00:00
else if ( is_token_symbol ( stix , VOCA_CLASS ) )
2015-05-15 14:55:12 +00:00
{
2015-05-25 18:13:52 +00:00
/* #class Selfclass(Superclass) { } */
2015-05-20 15:24:37 +00:00
GET_TOKEN ( stix ) ;
2015-07-06 13:27:49 +00:00
if ( compile_class_definition ( stix , 0 ) < = - 1 ) return - 1 ;
}
else if ( is_token_symbol ( stix , VOCA_EXTEND ) )
{
/* #extend Selfclass {} */
GET_TOKEN ( stix ) ;
if ( compile_class_definition ( stix , 1 ) < = - 1 ) return - 1 ;
2015-05-15 14:55:12 +00:00
}
2015-07-14 13:35:18 +00:00
else if ( is_token_symbol ( stix , VOCA_POOLDIC ) )
{
2016-07-01 16:31:47 +00:00
/* #pooldic SharedPoolDic { #ABC := 20. #DEFG := 'ayz' } */
2015-07-14 13:35:18 +00:00
GET_TOKEN ( stix ) ;
if ( compile_pooldic_definition ( stix ) < = - 1 ) return - 1 ;
}
2015-05-25 18:13:52 +00:00
#if 0
2015-06-03 17:24:11 +00:00
else if ( is_token_symbol ( stix , VOCA_MAIN ) )
2015-05-20 14:27:47 +00:00
{
2015-05-25 18:13:52 +00:00
/* #main */
/* TODO: implement this */
2015-05-20 14:27:47 +00:00
}
2015-05-25 18:13:52 +00:00
# endif
2015-05-20 14:27:47 +00:00
else
{
2016-08-29 07:39:09 +00:00
set_syntax_error ( stix , STIX_SYNERR_DIRECTIVE , TOKEN_LOC ( stix ) , TOKEN_NAME ( stix ) ) ;
2015-05-25 18:13:52 +00:00
return - 1 ;
2015-05-20 14:27:47 +00:00
}
2015-05-15 14:55:12 +00:00
}
return 0 ;
}
2015-05-19 15:16:18 +00:00
2015-05-25 17:10:49 +00:00
static void gc_compiler ( stix_t * stix )
{
2015-05-26 16:31:47 +00:00
/* called when garbage collection is performed */
2015-05-25 17:10:49 +00:00
if ( stix - > c )
{
2015-12-17 16:11:10 +00:00
stix_oow_t i ;
2015-05-31 16:44:56 +00:00
2015-05-27 17:16:50 +00:00
if ( stix - > c - > cls . self_oop )
stix - > c - > cls . self_oop = ( stix_oop_class_t ) stix_moveoop ( stix , ( stix_oop_t ) stix - > c - > cls . self_oop ) ;
2015-05-25 18:13:52 +00:00
2015-05-27 17:16:50 +00:00
if ( stix - > c - > cls . super_oop )
stix - > c - > cls . super_oop = stix_moveoop ( stix , stix - > c - > cls . super_oop ) ;
2015-05-31 16:44:56 +00:00
if ( stix - > c - > cls . mthdic_oop [ MTH_INSTANCE ] )
stix - > c - > cls . mthdic_oop [ MTH_INSTANCE ] = ( stix_oop_set_t ) stix_moveoop ( stix , ( stix_oop_t ) stix - > c - > cls . mthdic_oop [ MTH_INSTANCE ] ) ;
if ( stix - > c - > cls . mthdic_oop [ MTH_CLASS ] )
stix - > c - > cls . mthdic_oop [ MTH_CLASS ] = ( stix_oop_set_t ) stix_moveoop ( stix , ( stix_oop_t ) stix - > c - > cls . mthdic_oop [ MTH_CLASS ] ) ;
2015-07-13 15:35:52 +00:00
if ( stix - > c - > cls . ns_oop )
stix - > c - > cls . ns_oop = ( stix_oop_set_t ) stix_moveoop ( stix , ( stix_oop_t ) stix - > c - > cls . ns_oop ) ;
if ( stix - > c - > cls . superns_oop )
stix - > c - > cls . superns_oop = ( stix_oop_set_t ) stix_moveoop ( stix , ( stix_oop_t ) stix - > c - > cls . superns_oop ) ;
2015-07-26 14:38:34 +00:00
for ( i = 0 ; i < stix - > c - > cls . pooldic_count ; i + + )
{
stix - > c - > cls . pooldic_oops [ i ] = ( stix_oop_set_t ) stix_moveoop ( stix , ( stix_oop_t ) stix - > c - > cls . pooldic_oops [ i ] ) ;
}
2015-05-31 16:44:56 +00:00
for ( i = 0 ; i < stix - > c - > mth . literal_count ; i + + )
{
2015-07-15 08:39:18 +00:00
stix - > c - > mth . literals [ i ] = stix_moveoop ( stix , stix - > c - > mth . literals [ i ] ) ;
2015-05-31 16:44:56 +00:00
}
2015-06-23 14:00:26 +00:00
for ( i = 0 ; i < stix - > c - > mth . arlit_count ; i + + )
{
2015-07-15 08:39:18 +00:00
stix - > c - > mth . arlit [ i ] = stix_moveoop ( stix , stix - > c - > mth . arlit [ i ] ) ;
2015-06-23 14:00:26 +00:00
}
2015-05-25 17:10:49 +00:00
}
}
2015-05-19 15:16:18 +00:00
static void fini_compiler ( stix_t * stix )
{
2015-05-26 16:31:47 +00:00
/* called before the stix object is closed */
2015-05-19 15:16:18 +00:00
if ( stix - > c )
{
2015-12-17 16:11:10 +00:00
stix_oow_t i ;
2015-05-25 18:13:52 +00:00
2015-05-19 15:16:18 +00:00
clear_io_names ( stix ) ;
2015-05-22 15:09:45 +00:00
if ( stix - > c - > tok . name . ptr ) stix_freemem ( stix , stix - > c - > tok . name . ptr ) ;
2015-07-13 15:35:52 +00:00
if ( stix - > c - > cls . fqn . ptr ) stix_freemem ( stix , stix - > c - > cls . fqn . ptr ) ;
if ( stix - > c - > cls . superfqn . ptr ) stix_freemem ( stix , stix - > c - > cls . superfqn . ptr ) ;
2015-05-25 17:10:49 +00:00
2015-05-27 17:16:50 +00:00
for ( i = 0 ; i < STIX_COUNTOF ( stix - > c - > cls . vars ) ; i + + )
2015-05-25 18:13:52 +00:00
{
2015-05-27 17:16:50 +00:00
if ( stix - > c - > cls . vars [ i ] . ptr ) stix_freemem ( stix , stix - > c - > cls . vars [ i ] . ptr ) ;
2015-05-25 18:13:52 +00:00
}
2015-07-26 14:38:34 +00:00
if ( stix - > c - > cls . pooldic . ptr ) stix_freemem ( stix , stix - > c - > cls . pooldic . ptr ) ;
if ( stix - > c - > cls . pooldic_oops ) stix_freemem ( stix , stix - > c - > cls . pooldic_oops ) ;
2015-06-01 15:59:16 +00:00
if ( stix - > c - > mth . text . ptr ) stix_freemem ( stix , stix - > c - > mth . text . ptr ) ;
if ( stix - > c - > mth . assignees . ptr ) stix_freemem ( stix , stix - > c - > mth . assignees . ptr ) ;
2015-06-03 17:24:11 +00:00
if ( stix - > c - > mth . binsels . ptr ) stix_freemem ( stix , stix - > c - > mth . binsels . ptr ) ;
if ( stix - > c - > mth . kwsels . ptr ) stix_freemem ( stix , stix - > c - > mth . kwsels . ptr ) ;
2015-05-27 17:16:50 +00:00
if ( stix - > c - > mth . name . ptr ) stix_freemem ( stix , stix - > c - > mth . name . ptr ) ;
2015-06-01 15:59:16 +00:00
if ( stix - > c - > mth . tmprs . ptr ) stix_freemem ( stix , stix - > c - > mth . tmprs . ptr ) ;
2015-05-27 17:16:50 +00:00
if ( stix - > c - > mth . code . ptr ) stix_freemem ( stix , stix - > c - > mth . code . ptr ) ;
2015-05-31 16:44:56 +00:00
if ( stix - > c - > mth . literals ) stix_freemem ( stix , stix - > c - > mth . literals ) ;
2015-06-23 14:00:26 +00:00
if ( stix - > c - > mth . balit ) stix_freemem ( stix , stix - > c - > mth . balit ) ;
if ( stix - > c - > mth . arlit ) stix_freemem ( stix , stix - > c - > mth . arlit ) ;
2015-06-30 14:47:39 +00:00
if ( stix - > c - > mth . blk_tmprcnt ) stix_freemem ( stix , stix - > c - > mth . blk_tmprcnt ) ;
2015-05-22 15:09:45 +00:00
2015-05-19 15:16:18 +00:00
stix_freemem ( stix , stix - > c ) ;
stix - > c = STIX_NULL ;
}
}
2015-05-15 14:55:12 +00:00
2016-05-27 15:01:54 +00:00
int stix_compile ( stix_t * stix , stix_ioimpl_t io )
2015-05-15 14:55:12 +00:00
{
int n ;
if ( ! io )
{
stix - > errnum = STIX_EINVAL ;
return - 1 ;
}
2015-05-19 15:16:18 +00:00
if ( ! stix - > c )
{
stix_cb_t cb , * cbp ;
2015-05-25 17:10:49 +00:00
2015-05-19 15:16:18 +00:00
STIX_MEMSET ( & cb , 0 , STIX_SIZEOF ( cb ) ) ;
2015-05-25 17:10:49 +00:00
cb . gc = gc_compiler ;
2015-05-19 15:16:18 +00:00
cb . fini = fini_compiler ;
cbp = stix_regcb ( stix , & cb ) ;
if ( ! cbp ) return - 1 ;
stix - > c = stix_callocmem ( stix , STIX_SIZEOF ( * stix - > c ) ) ;
if ( ! stix - > c )
{
stix_deregcb ( stix , cbp ) ;
return - 1 ;
}
stix - > c - > ilchr_ucs . ptr = & stix - > c - > ilchr ;
stix - > c - > ilchr_ucs . len = 1 ;
}
2015-05-15 14:55:12 +00:00
2015-06-12 13:52:30 +00:00
/* Some IO names could have been stored in earlier calls to this function.
* I clear such names before i begin this function . i don ' t clear it
* at the end of this function because i may be referenced as an error
* location */
clear_io_names ( stix ) ;
/* initialize some key fields */
2015-05-15 14:55:12 +00:00
stix - > c - > impl = io ;
2015-06-12 13:52:30 +00:00
stix - > c - > nungots = 0 ;
2015-06-11 12:09:10 +00:00
2015-06-12 13:52:30 +00:00
/* The name field and the includer field are STIX_NULL
* for the main stream */
2015-06-11 12:09:10 +00:00
STIX_MEMSET ( & stix - > c - > arg , 0 , STIX_SIZEOF ( stix - > c - > arg ) ) ;
2015-05-15 14:55:12 +00:00
stix - > c - > arg . line = 1 ;
stix - > c - > arg . colm = 1 ;
/* open the top-level stream */
2015-06-12 13:52:30 +00:00
n = stix - > c - > impl ( stix , STIX_IO_OPEN , & stix - > c - > arg ) ;
2015-05-15 14:55:12 +00:00
if ( n < = - 1 ) return - 1 ;
2015-06-12 13:52:30 +00:00
/* the stream is open. set it as the current input stream */
stix - > c - > curinp = & stix - > c - > arg ;
/* compile the contents of the stream */
2015-05-19 15:16:18 +00:00
if ( compile_stream ( stix ) < = - 1 ) goto oops ;
2015-05-15 14:55:12 +00:00
/* close the stream */
STIX_ASSERT ( stix - > c - > curinp = = & stix - > c - > arg ) ;
stix - > c - > impl ( stix , STIX_IO_CLOSE , stix - > c - > curinp ) ;
2015-05-19 15:16:18 +00:00
2015-05-15 14:55:12 +00:00
return 0 ;
oops :
/* an error occurred and control has reached here
* probably , some included files might not have been
* closed . close them */
while ( stix - > c - > curinp ! = & stix - > c - > arg )
{
2016-05-27 15:01:54 +00:00
stix_ioarg_t * prev ;
2015-05-15 14:55:12 +00:00
/* nothing much to do about a close error */
stix - > c - > impl ( stix , STIX_IO_CLOSE , stix - > c - > curinp ) ;
prev = stix - > c - > curinp - > includer ;
STIX_ASSERT ( stix - > c - > curinp - > name ! = STIX_NULL ) ;
STIX_MMGR_FREE ( stix - > mmgr , stix - > c - > curinp ) ;
stix - > c - > curinp = prev ;
}
stix - > c - > impl ( stix , STIX_IO_CLOSE , stix - > c - > curinp ) ;
return - 1 ;
}
2015-05-19 15:16:18 +00:00
void stix_getsynerr ( stix_t * stix , stix_synerr_t * synerr )
{
STIX_ASSERT ( stix - > c ! = STIX_NULL ) ;
if ( synerr ) * synerr = stix - > c - > synerr ;
}