sizeof working?
This commit is contained in:
parent
6af5b34295
commit
46635e5748
4 changed files with 142 additions and 40 deletions
76
05/main.b
76
05/main.b
|
@ -17,6 +17,48 @@ global function_macros_size
|
||||||
global object_macros
|
global object_macros
|
||||||
global function_macros
|
global function_macros
|
||||||
|
|
||||||
|
; powers of 10, stored in the following format:
|
||||||
|
; ulong significand
|
||||||
|
; ulong exponent
|
||||||
|
; where for i = -1023..1023, powers_of_10 + 16*i points to an entry where
|
||||||
|
; 10^i = significand * 2^exponent
|
||||||
|
global powers_of_10
|
||||||
|
|
||||||
|
global types
|
||||||
|
global types_bytes_used
|
||||||
|
; ident list of type IDs
|
||||||
|
global typedefs
|
||||||
|
|
||||||
|
|
||||||
|
#include util.b
|
||||||
|
#include idents.b
|
||||||
|
#include constants.b
|
||||||
|
#include preprocess.b
|
||||||
|
#include tokenize.b
|
||||||
|
#include parse.b
|
||||||
|
|
||||||
|
function types_init
|
||||||
|
argument _types
|
||||||
|
argument ptypes_bytes_used
|
||||||
|
local i
|
||||||
|
local p
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
p = _types
|
||||||
|
:fill_initial_types_loop
|
||||||
|
*1p = i
|
||||||
|
p += 1
|
||||||
|
i += 1
|
||||||
|
if i <= 16 goto fill_initial_types_loop
|
||||||
|
p = _types + TYPE_POINTER_TO_CHAR
|
||||||
|
*1p = TYPE_POINTER
|
||||||
|
p += 1
|
||||||
|
*1p = TYPE_CHAR
|
||||||
|
p += 1
|
||||||
|
|
||||||
|
*8ptypes_bytes_used = p - types
|
||||||
|
return
|
||||||
|
|
||||||
function fprint_token_location
|
function fprint_token_location
|
||||||
argument fd
|
argument fd
|
||||||
argument token
|
argument token
|
||||||
|
@ -86,24 +128,6 @@ function compile_warning
|
||||||
byte 32
|
byte 32
|
||||||
byte 0
|
byte 0
|
||||||
|
|
||||||
; powers of 10, stored in the following format:
|
|
||||||
; ulong significand
|
|
||||||
; ulong exponent
|
|
||||||
; where for i = -1023..1023, powers_of_10 + 16*i points to an entry where
|
|
||||||
; 10^i = significand * 2^exponent
|
|
||||||
global powers_of_10
|
|
||||||
|
|
||||||
global types
|
|
||||||
global types_bytes_used
|
|
||||||
; ident list of type IDs
|
|
||||||
global typedefs
|
|
||||||
|
|
||||||
#include util.b
|
|
||||||
#include idents.b
|
|
||||||
#include constants.b
|
|
||||||
#include preprocess.b
|
|
||||||
#include tokenize.b
|
|
||||||
#include parse.b
|
|
||||||
|
|
||||||
function main
|
function main
|
||||||
argument argv2
|
argument argv2
|
||||||
|
@ -131,21 +155,7 @@ function main
|
||||||
function_macros = malloc(4000000)
|
function_macros = malloc(4000000)
|
||||||
|
|
||||||
types = malloc(16000000)
|
types = malloc(16000000)
|
||||||
i = 0
|
types_init(types, &types_bytes_used)
|
||||||
p = types
|
|
||||||
:fill_initial_types_loop
|
|
||||||
*1p = i
|
|
||||||
p += 1
|
|
||||||
i += 1
|
|
||||||
if i <= 16 goto fill_initial_types_loop
|
|
||||||
p = types + TYPE_POINTER_TO_CHAR
|
|
||||||
*1p = TYPE_POINTER
|
|
||||||
p += 1
|
|
||||||
*1p = TYPE_CHAR
|
|
||||||
p += 1
|
|
||||||
|
|
||||||
types_bytes_used = p - types
|
|
||||||
|
|
||||||
|
|
||||||
input_filename = .str_default_input_filename
|
input_filename = .str_default_input_filename
|
||||||
output_filename = .str_default_output_filename
|
output_filename = .str_default_output_filename
|
||||||
|
|
|
@ -3,5 +3,5 @@
|
||||||
long double d;
|
long double d;
|
||||||
} (*x)(void);
|
} (*x)(void);
|
||||||
*/
|
*/
|
||||||
typedef long int unsigned Foo[0?5?0:32:0?7:8];
|
typedef long int unsigned Foo[sizeof"hello"+sizeof(double[sizeof(int) * sizeof 3])];
|
||||||
/* */
|
/* */
|
||||||
|
|
101
05/parse.b
101
05/parse.b
|
@ -1,3 +1,29 @@
|
||||||
|
; is this token the start of a type?
|
||||||
|
function token_is_type
|
||||||
|
argument token
|
||||||
|
local c
|
||||||
|
c = *1token
|
||||||
|
if c == TOKEN_IDENTIFIER goto token_is_ident_type
|
||||||
|
if c == KEYWORD_UNSIGNED goto return_1
|
||||||
|
if c == KEYWORD_CHAR goto return_1
|
||||||
|
if c == KEYWORD_SHORT goto return_1
|
||||||
|
if c == KEYWORD_INT goto return_1
|
||||||
|
if c == KEYWORD_LONG goto return_1
|
||||||
|
if c == KEYWORD_FLOAT goto return_1
|
||||||
|
if c == KEYWORD_DOUBLE goto return_1
|
||||||
|
if c == KEYWORD_VOID goto return_1
|
||||||
|
if c == KEYWORD_STRUCT goto return_1
|
||||||
|
if c == KEYWORD_UNION goto return_1
|
||||||
|
if c == KEYWORD_ENUM goto return_1
|
||||||
|
goto return_0
|
||||||
|
:token_is_ident_type
|
||||||
|
token += 8
|
||||||
|
c = *8token
|
||||||
|
local b
|
||||||
|
b = ident_list_lookup(typedefs, c)
|
||||||
|
if b != 0 goto return_1
|
||||||
|
goto return_0
|
||||||
|
|
||||||
function parse_tokens
|
function parse_tokens
|
||||||
argument tokens
|
argument tokens
|
||||||
local token
|
local token
|
||||||
|
@ -268,8 +294,6 @@ function parse_type_to
|
||||||
byte 0
|
byte 0
|
||||||
:parse_function_type
|
:parse_function_type
|
||||||
p = suffix + 16
|
p = suffix + 16
|
||||||
local RRR
|
|
||||||
RRR = out
|
|
||||||
*1out = TYPE_FUNCTION
|
*1out = TYPE_FUNCTION
|
||||||
out += 1
|
out += 1
|
||||||
:function_type_loop
|
:function_type_loop
|
||||||
|
@ -743,7 +767,7 @@ function parse_expression
|
||||||
|
|
||||||
|
|
||||||
:parse_expr_unary
|
:parse_expr_unary
|
||||||
if c == KEYWORD_SIZEOF goto parse_expr_sizeof
|
if c == KEYWORD_SIZEOF goto parse_sizeof
|
||||||
*1out = unary_op_to_expression_type(c)
|
*1out = unary_op_to_expression_type(c)
|
||||||
c = *1out
|
c = *1out
|
||||||
out += 8
|
out += 8
|
||||||
|
@ -798,8 +822,44 @@ function parse_expression
|
||||||
byte 32
|
byte 32
|
||||||
byte 0
|
byte 0
|
||||||
|
|
||||||
:parse_expr_sizeof
|
:parse_sizeof
|
||||||
byte 0xcc ; @TODO
|
; little hack to avoid screwing up types like double[sizeof(int)]
|
||||||
|
; temporarily switch out types array to parse the sizeof's type
|
||||||
|
local prev_types
|
||||||
|
local prev_types_bytes_used
|
||||||
|
prev_types = types
|
||||||
|
prev_types_bytes_used = types_bytes_used
|
||||||
|
types = malloc(4000)
|
||||||
|
types_init(types, &types_bytes_used)
|
||||||
|
*1out = EXPRESSION_CONSTANT_INT
|
||||||
|
out += 4
|
||||||
|
*1out = TYPE_UNSIGNED_LONG
|
||||||
|
out += 4
|
||||||
|
p = best + 16
|
||||||
|
if *1p != SYMBOL_LPAREN goto parse_sizeof_expr
|
||||||
|
p += 16
|
||||||
|
b = token_is_type(p)
|
||||||
|
if b == 0 goto parse_sizeof_expr
|
||||||
|
; it's a type, e.g. sizeof(int)
|
||||||
|
a = parse_type(&p, &c)
|
||||||
|
if c != 0 goto bad_expression ; e.g. sizeof(int x)
|
||||||
|
*8out = type_sizeof(a)
|
||||||
|
goto parse_sizeof_finish
|
||||||
|
:parse_sizeof_expr
|
||||||
|
; it's an expression, e.g. sizeof(x+3)
|
||||||
|
local temp
|
||||||
|
temp = malloc(4000)
|
||||||
|
p = best + 16
|
||||||
|
parse_expression(p, tokens_end, temp)
|
||||||
|
p = temp + 4
|
||||||
|
*8out = type_sizeof(*4p)
|
||||||
|
free(temp)
|
||||||
|
:parse_sizeof_finish
|
||||||
|
free(types)
|
||||||
|
types = prev_types
|
||||||
|
types_bytes_used = prev_types_bytes_used
|
||||||
|
out += 8
|
||||||
|
return out
|
||||||
|
|
||||||
:parse_expr_member ; -> or .
|
:parse_expr_member ; -> or .
|
||||||
p = best + 16
|
p = best + 16
|
||||||
|
@ -978,6 +1038,37 @@ function parse_expression
|
||||||
:return_type_double
|
:return_type_double
|
||||||
return TYPE_DOUBLE
|
return TYPE_DOUBLE
|
||||||
|
|
||||||
|
function type_sizeof
|
||||||
|
argument type
|
||||||
|
local p
|
||||||
|
local c
|
||||||
|
p = types + type
|
||||||
|
c = *1p
|
||||||
|
if c == TYPE_CHAR goto return_1
|
||||||
|
if c == TYPE_UNSIGNED_CHAR goto return_1
|
||||||
|
if c == TYPE_SHORT goto return_2
|
||||||
|
if c == TYPE_UNSIGNED_SHORT goto return_2
|
||||||
|
if c == TYPE_INT goto return_4
|
||||||
|
if c == TYPE_UNSIGNED_INT goto return_4
|
||||||
|
if c == TYPE_LONG goto return_8
|
||||||
|
if c == TYPE_UNSIGNED_LONG goto return_8
|
||||||
|
if c == TYPE_FLOAT goto return_4
|
||||||
|
if c == TYPE_DOUBLE goto return_8
|
||||||
|
if c == TYPE_VOID goto return_1
|
||||||
|
if c == TYPE_POINTER goto return_8
|
||||||
|
if c == TYPE_FUNCTION goto return_8
|
||||||
|
if c == TYPE_ARRAY goto sizeof_array
|
||||||
|
byte 0xcc ; @TODO
|
||||||
|
|
||||||
|
:sizeof_array
|
||||||
|
local n
|
||||||
|
p += 1
|
||||||
|
n = *8p
|
||||||
|
p += 8
|
||||||
|
p -= types
|
||||||
|
c = type_sizeof(p)
|
||||||
|
return n * c
|
||||||
|
|
||||||
; evaluate an expression which can be the size of an array, e.g.
|
; evaluate an expression which can be the size of an array, e.g.
|
||||||
; enum { A, B, C };
|
; enum { A, B, C };
|
||||||
; int x[A * sizeof(float) + 3 << 5];
|
; int x[A * sizeof(float) + 3 << 5];
|
||||||
|
|
|
@ -843,6 +843,7 @@ function translation_phase_4
|
||||||
macro_replacement_to_terminator(filename, line_number, &in, &p, 10)
|
macro_replacement_to_terminator(filename, line_number, &in, &p, 10)
|
||||||
;@TODO: there's no point in doing this until we have parsing
|
;@TODO: there's no point in doing this until we have parsing
|
||||||
; we'll have to evaluate constant expressions anyways for array declarations
|
; we'll have to evaluate constant expressions anyways for array declarations
|
||||||
|
free(if_pptokens)
|
||||||
fputs(2, .str_if_not_implemented)
|
fputs(2, .str_if_not_implemented)
|
||||||
byte 0xcc
|
byte 0xcc
|
||||||
:str_if_not_implemented
|
:str_if_not_implemented
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue