start string initializers
This commit is contained in:
parent
44e11303be
commit
22859ac40a
3 changed files with 48 additions and 28 deletions
17
05/main.c
17
05/main.c
|
@ -27,20 +27,9 @@
|
||||||
/* typedef int x[sizeof(A)+sizeof"hello"]; */
|
/* typedef int x[sizeof(A)+sizeof"hello"]; */
|
||||||
/* typedef int y[sizeof(struct B)]; */
|
/* typedef int y[sizeof(struct B)]; */
|
||||||
|
|
||||||
static unsigned int x;
|
static unsigned int x=55;
|
||||||
static unsigned int y;
|
static char *s = "hello";
|
||||||
static unsigned int z[1000];
|
static char *t = "goodbye";
|
||||||
static unsigned int w;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int x;
|
|
||||||
} Test;
|
|
||||||
|
|
||||||
int a = -138;
|
|
||||||
double f = 0;
|
|
||||||
void *p = 0;
|
|
||||||
int j = 3+7<<5, k = 123;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
NOTE: THIS MUST WORK
|
NOTE: THIS MUST WORK
|
||||||
int x[] = {1,2,3}
|
int x[] = {1,2,3}
|
||||||
|
|
57
05/parse.b
57
05/parse.b
|
@ -229,7 +229,7 @@ function parse_tokens
|
||||||
; advances *p_token to the token right after the initializer
|
; advances *p_token to the token right after the initializer
|
||||||
; if `type` refers to a sizeless array type (e.g. int x[] = {1,2,3};), it will be altered to the correct size
|
; if `type` refers to a sizeless array type (e.g. int x[] = {1,2,3};), it will be altered to the correct size
|
||||||
; outputs the initializer data to rwdata_end_addr, and advances it accordingly.
|
; outputs the initializer data to rwdata_end_addr, and advances it accordingly.
|
||||||
; after calling this, make sure you update rwdata_end_addr to a multiple of 8 if necessary
|
; after calling this, make sure to align rwdata_end_addr properly
|
||||||
function parse_constant_initializer
|
function parse_constant_initializer
|
||||||
argument p_token
|
argument p_token
|
||||||
argument type
|
argument type
|
||||||
|
@ -272,6 +272,9 @@ function parse_constant_initializer
|
||||||
|
|
||||||
if *1token == SYMBOL_LBRACE goto parse_braced_initializer
|
if *1token == SYMBOL_LBRACE goto parse_braced_initializer
|
||||||
if *1token == TOKEN_STRING_LITERAL goto parse_string_literal_initializer
|
if *1token == TOKEN_STRING_LITERAL goto parse_string_literal_initializer
|
||||||
|
|
||||||
|
; an ordinary expression
|
||||||
|
|
||||||
p = types + type
|
p = types + type
|
||||||
if *1p > TYPE_POINTER goto expression_initializer_for_nonscalar_type
|
if *1p > TYPE_POINTER goto expression_initializer_for_nonscalar_type
|
||||||
|
|
||||||
|
@ -284,7 +287,6 @@ function parse_constant_initializer
|
||||||
c = type_sizeof(type)
|
c = type_sizeof(type)
|
||||||
p = output_file_data + rwdata_end_addr
|
p = output_file_data + rwdata_end_addr
|
||||||
rwdata_end_addr += c
|
rwdata_end_addr += c
|
||||||
*8p_token = end
|
|
||||||
if c == 1 goto write_initializer1
|
if c == 1 goto write_initializer1
|
||||||
if c == 2 goto write_initializer2
|
if c == 2 goto write_initializer2
|
||||||
if c == 4 goto write_initializer4
|
if c == 4 goto write_initializer4
|
||||||
|
@ -295,27 +297,52 @@ function parse_constant_initializer
|
||||||
byte 0
|
byte 0
|
||||||
:write_initializer1
|
:write_initializer1
|
||||||
*1p = value
|
*1p = value
|
||||||
return
|
goto const_init_ret
|
||||||
:write_initializer2
|
:write_initializer2
|
||||||
*2p = value
|
*2p = value
|
||||||
return
|
goto const_init_ret
|
||||||
:write_initializer4
|
:write_initializer4
|
||||||
*4p = value
|
*4p = value
|
||||||
return
|
goto const_init_ret
|
||||||
:write_initializer8
|
:write_initializer8
|
||||||
*8p = value
|
*8p = value
|
||||||
return
|
goto const_init_ret
|
||||||
|
|
||||||
|
|
||||||
:init_floating_check ; also checks pointer types (e.g. don't do static void *x = 1;)
|
:init_floating_check ; also checks pointer types (e.g. don't do static void *x = 1;)
|
||||||
if value != 0 goto floating_initializer_other_than_0
|
if value != 0 goto floating_initializer_other_than_0
|
||||||
goto init_good
|
goto init_good
|
||||||
|
|
||||||
|
:const_init_ret
|
||||||
|
*8p_token = end
|
||||||
|
return
|
||||||
|
|
||||||
:parse_braced_initializer
|
:parse_braced_initializer
|
||||||
byte 0xcc ; @TODO
|
byte 0xcc ; @TODO
|
||||||
:parse_string_literal_initializer
|
:parse_string_literal_initializer
|
||||||
byte 0xcc ; @TODO
|
p = token + 16
|
||||||
|
if p != end goto stuff_after_string_literal
|
||||||
|
p = types + type
|
||||||
|
if *1p == TYPE_ARRAY goto string_literal_array_initializer
|
||||||
|
if *1p != TYPE_POINTER goto string_literal_bad_type
|
||||||
|
p += 1
|
||||||
|
if *1p != TYPE_CHAR goto string_literal_bad_type
|
||||||
|
token += 8
|
||||||
|
p = output_file_data + rwdata_end_addr
|
||||||
|
*8p = *8token
|
||||||
|
rwdata_end_addr += 8
|
||||||
|
goto const_init_ret
|
||||||
|
|
||||||
|
:string_literal_array_initializer
|
||||||
|
byte 0xcc
|
||||||
|
:stuff_after_string_literal
|
||||||
|
token_error(token, .str_stuff_after_string_literal)
|
||||||
|
:str_stuff_after_string_literal
|
||||||
|
string Stuff after string literal in initializer.
|
||||||
|
byte 0
|
||||||
|
:string_literal_bad_type
|
||||||
|
token_error(token, .str_string_literal_bad_type)
|
||||||
|
:str_string_literal_bad_type
|
||||||
|
string Bad type for string literal initializer (i.e. not char* or char[]).
|
||||||
|
byte 0
|
||||||
:find_init_end_eof
|
:find_init_end_eof
|
||||||
token_error(token, .str_find_init_end_eof)
|
token_error(token, .str_find_init_end_eof)
|
||||||
:str_find_init_end_eof
|
:str_find_init_end_eof
|
||||||
|
@ -1890,10 +1917,13 @@ function evaluate_constant_expression
|
||||||
byte 0
|
byte 0
|
||||||
:eval_cast
|
:eval_cast
|
||||||
p = types + type
|
p = types + type
|
||||||
if *1p == TYPE_VOID goto eval_cast_bad_type
|
c = *1p
|
||||||
if *1p > TYPE_UNSIGNED_LONG goto eval_cast_bad_type
|
if c == TYPE_VOID goto eval_cast_bad_type
|
||||||
expr += 8
|
|
||||||
; @NONSTANDARD: we don't support, for example, int x[(int)(float)5];
|
; @NONSTANDARD: we don't support, for example, int x[(int)(float)5];
|
||||||
|
if c == TYPE_FLOAT goto eval_cast_bad_type
|
||||||
|
if c == TYPE_DOUBLE goto eval_cast_bad_type
|
||||||
|
if c > TYPE_POINTER goto eval_cast_bad_type
|
||||||
|
expr += 8
|
||||||
expr = evaluate_constant_expression(token, expr, p_value)
|
expr = evaluate_constant_expression(token, expr, p_value)
|
||||||
goto eval_fit_to_type
|
goto eval_fit_to_type
|
||||||
:eval_cast_bad_type
|
:eval_cast_bad_type
|
||||||
|
@ -2124,6 +2154,7 @@ function fit_to_type
|
||||||
if c == TYPE_UNSIGNED_INT goto fit_to_type_uint
|
if c == TYPE_UNSIGNED_INT goto fit_to_type_uint
|
||||||
if c == TYPE_LONG goto fit_to_type_long
|
if c == TYPE_LONG goto fit_to_type_long
|
||||||
if c == TYPE_UNSIGNED_LONG goto fit_to_type_ulong
|
if c == TYPE_UNSIGNED_LONG goto fit_to_type_ulong
|
||||||
|
if c == TYPE_POINTER goto fit_to_type_ulong
|
||||||
fputs(2, .str_bad_fit_to_type)
|
fputs(2, .str_bad_fit_to_type)
|
||||||
exit(1)
|
exit(1)
|
||||||
:str_bad_fit_to_type
|
:str_bad_fit_to_type
|
||||||
|
|
|
@ -103,7 +103,7 @@ function get_keyword_str
|
||||||
; uchar info
|
; uchar info
|
||||||
; ushort file
|
; ushort file
|
||||||
; uint line
|
; uint line
|
||||||
; ulong data
|
; ulong data -- for int/float literals, the value; for string literals, the runtime address; for identifiers, the name of the identifier
|
||||||
; This corresponds to translation phases 5-6 and the first half of 7
|
; This corresponds to translation phases 5-6 and the first half of 7
|
||||||
; IMPORTANT: this function uses pointers to pptokens, so it should NOT be freed!
|
; IMPORTANT: this function uses pointers to pptokens, so it should NOT be freed!
|
||||||
; Returns a pointer to the end of tokens.
|
; Returns a pointer to the end of tokens.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue