more parsing tests, fixed more bugs
- we now handle incomplete structs properly - small fix in for loop printing
This commit is contained in:
parent
c548b12bbb
commit
d74dc53b0b
7 changed files with 4049 additions and 24 deletions
|
@ -244,7 +244,7 @@
|
||||||
; reading the first 16 bits of type data as a word will give this if the type refers to a function pointer.
|
; reading the first 16 bits of type data as a word will give this if the type refers to a function pointer.
|
||||||
#define TYPE2_FUNCTION_POINTER 0x100d
|
#define TYPE2_FUNCTION_POINTER 0x100d
|
||||||
|
|
||||||
; types willl be initialized (in main) so that these will refer to the proper types
|
; types will be initialized (in main) so that these will refer to the proper types
|
||||||
#define TYPE_POINTER_TO_CHAR 20
|
#define TYPE_POINTER_TO_CHAR 20
|
||||||
#define TYPE_POINTER_TO_VOID 22
|
#define TYPE_POINTER_TO_VOID 22
|
||||||
|
|
||||||
|
|
28
05/idents.b
28
05/idents.b
|
@ -85,6 +85,34 @@ function ident_list_lookup
|
||||||
list -= 8 ; backtrack to value
|
list -= 8 ; backtrack to value
|
||||||
return *8list ; UNALIGNED
|
return *8list ; UNALIGNED
|
||||||
|
|
||||||
|
; return a pointer to the value associated with ident, or 0 if none is
|
||||||
|
function ident_list_lookup_pointer
|
||||||
|
argument list
|
||||||
|
argument ident
|
||||||
|
local b
|
||||||
|
:ilist_lookup_pointer_loop
|
||||||
|
if *1list == 0 goto return_0
|
||||||
|
b = str_equals(list, ident)
|
||||||
|
list = memchr(list, 0)
|
||||||
|
list += 9 ; skip null byte and value
|
||||||
|
if b == 0 goto ilist_lookup_pointer_loop
|
||||||
|
list -= 8 ; backtrack to value
|
||||||
|
return list
|
||||||
|
|
||||||
|
; if list contains ident, change its value to `value`. otherwise, add ident with the given value.
|
||||||
|
function ident_list_set
|
||||||
|
argument list
|
||||||
|
argument ident
|
||||||
|
argument value
|
||||||
|
local p
|
||||||
|
p = ident_list_lookup_pointer(list, ident)
|
||||||
|
if p == 0 goto ident_list_set_add
|
||||||
|
*8p = value
|
||||||
|
return
|
||||||
|
:ident_list_set_add
|
||||||
|
ident_list_add(list, ident, value)
|
||||||
|
return
|
||||||
|
|
||||||
; if identifier in list, sets *pvalue to its value (if pvalue is not null) and returns 1
|
; if identifier in list, sets *pvalue to its value (if pvalue is not null) and returns 1
|
||||||
; otherwise, returns 0
|
; otherwise, returns 0
|
||||||
function ident_list_lookup_check
|
function ident_list_lookup_check
|
||||||
|
|
|
@ -72,6 +72,8 @@ global expressions_end
|
||||||
; current rbp offset (where rsp is)
|
; current rbp offset (where rsp is)
|
||||||
global local_var_rbp_offset
|
global local_var_rbp_offset
|
||||||
global function_param_names
|
global function_param_names
|
||||||
|
; set to 1 by parse_type_declarators if at least one function parameter has no name.
|
||||||
|
global function_param_has_no_name
|
||||||
|
|
||||||
#include util.b
|
#include util.b
|
||||||
#include idents.b
|
#include idents.b
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* #include "tests/parse_stb_truetype.h" */
|
#include "tests/parse_stb_truetype.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
; @NONSTANDARD:
|
; @NONSTANDARD:
|
||||||
|
|
75
05/parse.b
75
05/parse.b
|
@ -240,6 +240,7 @@ function parse_toplevel_declaration
|
||||||
byte 0
|
byte 0
|
||||||
:parse_function_definition
|
:parse_function_definition
|
||||||
if block_depth != 0 goto nested_function
|
if block_depth != 0 goto nested_function
|
||||||
|
if function_param_has_no_name != 0 goto function_no_param_name
|
||||||
p = types + type
|
p = types + type
|
||||||
if *1p != TYPE_FUNCTION goto lbrace_after_declaration
|
if *1p != TYPE_FUNCTION goto lbrace_after_declaration
|
||||||
|
|
||||||
|
@ -280,6 +281,11 @@ function parse_toplevel_declaration
|
||||||
print_statement(out0)
|
print_statement(out0)
|
||||||
goto parse_tld_ret
|
goto parse_tld_ret
|
||||||
|
|
||||||
|
:function_no_param_name
|
||||||
|
token_error(base_type, .str_function_no_param_name)
|
||||||
|
:str_function_no_param_name
|
||||||
|
string Function definition with unnamed parameters.
|
||||||
|
byte 0
|
||||||
:blockdepth_internal_err
|
:blockdepth_internal_err
|
||||||
token_error(token, .str_blockdepth_internal_err)
|
token_error(token, .str_blockdepth_internal_err)
|
||||||
:str_blockdepth_internal_err
|
:str_blockdepth_internal_err
|
||||||
|
@ -660,6 +666,17 @@ function parse_statement
|
||||||
parse_type_declarators(l_prefix, l_prefix_end, l_suffix, l_suffix_end, 0)
|
parse_type_declarators(l_prefix, l_prefix_end, l_suffix, l_suffix_end, 0)
|
||||||
parse_base_type(l_base_type)
|
parse_base_type(l_base_type)
|
||||||
|
|
||||||
|
; create pseudo-entry for variable in local variables list.
|
||||||
|
; this allows for int *x = malloc(sizeof *x);
|
||||||
|
; unfortunately, it also allows int x = x;
|
||||||
|
; oh well
|
||||||
|
p = local_variables
|
||||||
|
p += block_depth < 3
|
||||||
|
c = ident_list_lookup(*8p, l_name)
|
||||||
|
if c != 0 goto local_redeclaration
|
||||||
|
c = l_type < 32
|
||||||
|
ident_list_add(*8p, l_name, c)
|
||||||
|
|
||||||
|
|
||||||
token = l_suffix_end
|
token = l_suffix_end
|
||||||
if *1token == SYMBOL_EQ goto local_decl_initializer
|
if *1token == SYMBOL_EQ goto local_decl_initializer
|
||||||
|
@ -682,11 +699,9 @@ function parse_statement
|
||||||
p = local_variables
|
p = local_variables
|
||||||
p += block_depth < 3
|
p += block_depth < 3
|
||||||
l_offset = local_var_rbp_offset
|
l_offset = local_var_rbp_offset
|
||||||
c = ident_list_lookup(*8p, l_name)
|
|
||||||
if c != 0 goto local_redeclaration
|
|
||||||
c = l_offset
|
c = l_offset
|
||||||
c |= l_type < 32
|
c |= l_type < 32
|
||||||
ident_list_add(*8p, l_name, c)
|
ident_list_set(*8p, l_name, c)
|
||||||
|
|
||||||
if *1token == SYMBOL_SEMICOLON goto local_decl_loop_end
|
if *1token == SYMBOL_SEMICOLON goto local_decl_loop_end
|
||||||
if *1token != SYMBOL_COMMA goto local_decl_badsuffix
|
if *1token != SYMBOL_COMMA goto local_decl_badsuffix
|
||||||
|
@ -989,7 +1004,7 @@ function print_statement_with_depth
|
||||||
print_expression(dat2)
|
print_expression(dat2)
|
||||||
:print_for_noexpr2
|
:print_for_noexpr2
|
||||||
puts(.str_for_sep)
|
puts(.str_for_sep)
|
||||||
if dat2 == 0 goto print_for_noexpr3
|
if dat3 == 0 goto print_for_noexpr3
|
||||||
print_expression(dat3)
|
print_expression(dat3)
|
||||||
:print_for_noexpr3
|
:print_for_noexpr3
|
||||||
putcln(41)
|
putcln(41)
|
||||||
|
@ -1415,7 +1430,7 @@ function parse_constant_initializer
|
||||||
:floating_initializer_other_than_0
|
:floating_initializer_other_than_0
|
||||||
token_error(token, .str_floating_initializer_other_than_0)
|
token_error(token, .str_floating_initializer_other_than_0)
|
||||||
:str_floating_initializer_other_than_0
|
:str_floating_initializer_other_than_0
|
||||||
string Only 0 is supported as a floating-point initializer.
|
string Only 0 is supported as a constant floating-point initializer.
|
||||||
byte 0
|
byte 0
|
||||||
; *p_token should be pointing to a {, this will advance it to point to the matching }
|
; *p_token should be pointing to a {, this will advance it to point to the matching }
|
||||||
function token_skip_to_matching_rbrace
|
function token_skip_to_matching_rbrace
|
||||||
|
@ -1825,6 +1840,13 @@ function parse_type_declarators
|
||||||
local param_suffix_end
|
local param_suffix_end
|
||||||
local d
|
local d
|
||||||
|
|
||||||
|
if param_names_out == 0 goto skip_ftype_reset
|
||||||
|
; this gets set to 1 if at least one parameter has no name.
|
||||||
|
; we don't just error here, because we need to support declarations like:
|
||||||
|
; int f(int, int);
|
||||||
|
function_param_has_no_name = 0
|
||||||
|
:skip_ftype_reset
|
||||||
|
|
||||||
out = types + types_bytes_used
|
out = types + types_bytes_used
|
||||||
*1out = TYPE_FUNCTION
|
*1out = TYPE_FUNCTION
|
||||||
types_bytes_used += 1
|
types_bytes_used += 1
|
||||||
|
@ -1898,10 +1920,8 @@ function parse_type_declarators
|
||||||
suffix = p + 16
|
suffix = p + 16
|
||||||
goto type_declarators_loop
|
goto type_declarators_loop
|
||||||
:no_param_name
|
:no_param_name
|
||||||
token_error(param_suffix, .str_no_param_name)
|
function_param_has_no_name = 1
|
||||||
:str_no_param_name
|
goto functype_had_ident
|
||||||
string Function parameter has no name.
|
|
||||||
byte 0
|
|
||||||
:stuff_after_ftype_varargs
|
:stuff_after_ftype_varargs
|
||||||
token_error(p, .str_stuff_after_ftype_varargs)
|
token_error(p, .str_stuff_after_ftype_varargs)
|
||||||
:str_stuff_after_ftype_varargs
|
:str_stuff_after_ftype_varargs
|
||||||
|
@ -2080,18 +2100,21 @@ function parse_base_type
|
||||||
c = ident_list_lookup(structures, struct_name)
|
c = ident_list_lookup(structures, struct_name)
|
||||||
if *1p == SYMBOL_LBRACE goto base_type_struct_definition
|
if *1p == SYMBOL_LBRACE goto base_type_struct_definition
|
||||||
|
|
||||||
if c == 0 goto base_type_incomplete_struct
|
if c == 0 goto base_type_new_incomplete_struct
|
||||||
; e.g. struct Foo x; where struct Foo has been defined
|
:base_type_named_struct
|
||||||
|
; e.g. struct Foo x;
|
||||||
*1out = TYPE_STRUCT
|
*1out = TYPE_STRUCT
|
||||||
out += 1
|
out += 1
|
||||||
*8out = c
|
*8out = c
|
||||||
out += 8
|
out += 8
|
||||||
goto base_type_done
|
goto base_type_done
|
||||||
:base_type_incomplete_struct
|
:base_type_new_incomplete_struct
|
||||||
; e.g. struct Foo *x; where struct Foo hasn't been defined
|
; create an ident list for the incomplete struct, with nothing in it yet
|
||||||
*1out = TYPE_VOID
|
struct = ident_list_create(8000)
|
||||||
out += 1
|
; add it to the table
|
||||||
goto base_type_done
|
ident_list_add(structures, struct_name, struct)
|
||||||
|
c = struct
|
||||||
|
goto base_type_named_struct
|
||||||
:base_type_struct_definition
|
:base_type_struct_definition
|
||||||
; @NONSTANDARD: we don't handle bit-fields.
|
; @NONSTANDARD: we don't handle bit-fields.
|
||||||
local struct_location
|
local struct_location
|
||||||
|
@ -2107,8 +2130,18 @@ function parse_base_type
|
||||||
|
|
||||||
struct_location = token_get_location(p)
|
struct_location = token_get_location(p)
|
||||||
|
|
||||||
if c != 0 goto struct_maybe_redefinition
|
if c == 0 goto completely_new_struct
|
||||||
|
if *1c != 0 goto struct_maybe_redefinition
|
||||||
|
; ok we're filling in an incomplete struct
|
||||||
|
struct = c
|
||||||
|
goto struct_definition_fill_in
|
||||||
|
|
||||||
|
:completely_new_struct
|
||||||
|
; a completely new struct; hasn't been used as an incomplete struct
|
||||||
struct = ident_list_create(8000) ; note: maximum "* 127 members in a single structure or union" C89 § 2.2.4.1
|
struct = ident_list_create(8000) ; note: maximum "* 127 members in a single structure or union" C89 § 2.2.4.1
|
||||||
|
ident_list_add(structures, struct_name, struct)
|
||||||
|
|
||||||
|
:struct_definition_fill_in
|
||||||
*1out = TYPE_STRUCT
|
*1out = TYPE_STRUCT
|
||||||
out += 1
|
out += 1
|
||||||
*8out = struct
|
*8out = struct
|
||||||
|
@ -2120,7 +2153,6 @@ function parse_base_type
|
||||||
offset = 0
|
offset = 0
|
||||||
|
|
||||||
if *1struct_name == 0 goto struct_unnamed
|
if *1struct_name == 0 goto struct_unnamed
|
||||||
ident_list_add(structures, struct_name, struct)
|
|
||||||
ident_list_add(structure_locations, struct_name, struct_location)
|
ident_list_add(structure_locations, struct_name, struct_location)
|
||||||
:struct_unnamed
|
:struct_unnamed
|
||||||
|
|
||||||
|
@ -2865,6 +2897,7 @@ function parse_expression
|
||||||
if *1a != TYPE_STRUCT goto member_non_struct
|
if *1a != TYPE_STRUCT goto member_non_struct
|
||||||
a += 1
|
a += 1
|
||||||
a = *8a ; pointer to struct data
|
a = *8a ; pointer to struct data
|
||||||
|
if *1a == 0 goto use_of_incomplete_struct
|
||||||
p += 8
|
p += 8
|
||||||
c = ident_list_lookup(a, *8p)
|
c = ident_list_lookup(a, *8p)
|
||||||
if c == 0 goto member_not_in_struct
|
if c == 0 goto member_not_in_struct
|
||||||
|
@ -2874,6 +2907,11 @@ function parse_expression
|
||||||
p += 8
|
p += 8
|
||||||
if p != tokens_end goto bad_expression ; e.g. foo->bar hello
|
if p != tokens_end goto bad_expression ; e.g. foo->bar hello
|
||||||
return out
|
return out
|
||||||
|
:use_of_incomplete_struct
|
||||||
|
token_error(p, .str_use_of_incomplete_struct)
|
||||||
|
:str_use_of_incomplete_struct
|
||||||
|
string Use of incomplete struct.
|
||||||
|
byte 0
|
||||||
:arrow_non_pointer
|
:arrow_non_pointer
|
||||||
token_error(p, .str_arrow_non_pointer)
|
token_error(p, .str_arrow_non_pointer)
|
||||||
:str_arrow_non_pointer
|
:str_arrow_non_pointer
|
||||||
|
@ -2885,6 +2923,7 @@ function parse_expression
|
||||||
string Trying to access member of something other than a (complete) structure/union.
|
string Trying to access member of something other than a (complete) structure/union.
|
||||||
byte 0
|
byte 0
|
||||||
:member_not_in_struct
|
:member_not_in_struct
|
||||||
|
p -= 8
|
||||||
token_error(p, .str_member_not_in_struct)
|
token_error(p, .str_member_not_in_struct)
|
||||||
:str_member_not_in_struct
|
:str_member_not_in_struct
|
||||||
string Trying to access non-existent member of structure or union.
|
string Trying to access non-existent member of structure or union.
|
||||||
|
|
3956
05/tests/parse_stb_tilemap_editor.h
Normal file
3956
05/tests/parse_stb_tilemap_editor.h
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1634,7 +1634,7 @@ static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo *info, int glyph_index, s
|
||||||
stbtt_uint16 flags, gidx;
|
stbtt_uint16 flags, gidx;
|
||||||
int comp_num_verts = 0, i;
|
int comp_num_verts = 0, i;
|
||||||
stbtt_vertex *comp_verts = 0, *tmp = 0;
|
stbtt_vertex *comp_verts = 0, *tmp = 0;
|
||||||
float mtx[6] = {1,0,0,1,0,0}, m, n;
|
float mtx[6] = {0,0,0,0,0,0}, m, n;
|
||||||
|
|
||||||
flags = ttSHORT(comp); comp+=2;
|
flags = ttSHORT(comp); comp+=2;
|
||||||
gidx = ttSHORT(comp); comp+=2;
|
gidx = ttSHORT(comp); comp+=2;
|
||||||
|
@ -4282,7 +4282,7 @@ static int equal(float *a, float *b)
|
||||||
static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex *verts)
|
static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex *verts)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
float orig[2], ray[2] = { 1, 0 };
|
float orig[2], ray[2] = { 0, 0 };
|
||||||
float y_frac;
|
float y_frac;
|
||||||
int winding = 0;
|
int winding = 0;
|
||||||
|
|
||||||
|
@ -4497,7 +4497,7 @@ STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float sc
|
||||||
float ax = x1-x0, ay = y1-y0;
|
float ax = x1-x0, ay = y1-y0;
|
||||||
float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2;
|
float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2;
|
||||||
float mx = x0 - sx, my = y0 - sy;
|
float mx = x0 - sx, my = y0 - sy;
|
||||||
float res[3] = {0.f,0.f,0.f};
|
float res[3] = {0,0,0};
|
||||||
float px,py,t,it,dist2;
|
float px,py,t,it,dist2;
|
||||||
float a_inv = precompute[i];
|
float a_inv = precompute[i];
|
||||||
if (a_inv == 0.0) {
|
if (a_inv == 0.0) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue