Parser: Started to support proper errors as values, error recovery, and verbose testing of upfront and parsing interface.
Also fix to c_library generation for Genric_ on code body.
This commit is contained in:
1 parent
ed755e34f1
commit
8ba02de6ed
9 files changed
+1982
-604
No files matched your search
@@ -11,8 +11,7 @@
|
||||
ParseInfo wip_parse_str(LexedInfo lexed, ParseOpts* opts)
|
||||
{
|
||||
// TODO(Ed): Lift this.
|
||||
Context* ctx = _ctx;
|
||||
ParseInfo info = struct_zero(ParseInfo);
|
||||
Context* ctx = _ctx; ParseInfo info = struct_zero(ParseInfo);
|
||||
|
||||
if (lexed.tokens.num == 0 && lexed.tokens.ptr == nullptr) {
|
||||
ctx->parser = struct_zero(ParseContext);
|
||||
@@ -26,92 +25,74 @@ ParseInfo wip_parse_str(LexedInfo lexed, ParseOpts* opts)
|
||||
|
||||
// TODO(Ed): ParseInfo should be set to the parser context.
|
||||
|
||||
ctx->parser = struct_zero(ParseContext);
|
||||
ctx->parser.tokens = lexed.tokens;
|
||||
|
||||
{
|
||||
ParseStackNode scope = NullScope;
|
||||
parser_push(& ctx->parser, & scope);
|
||||
|
||||
CodeBody result = parse_global_nspace(ctx,CT_Global_Body);
|
||||
(void)result;
|
||||
|
||||
parser_pop(& ctx->parser);
|
||||
ctx->parser = struct_zero(ParseContext);
|
||||
ctx->parser.tokens = lexed.tokens; {
|
||||
ctx->parser.lexed_messages = lexed.messages;
|
||||
ParseStackNode scope = NullScope; parser_push(& ctx->parser, & scope);
|
||||
CodeBody result = parse_global_nspace(ctx,CT_Global_Body); (void)result;
|
||||
parser_pop(& ctx->parser);
|
||||
}
|
||||
done:
|
||||
return info;
|
||||
}
|
||||
|
||||
CodeClass parse_class( Str def )
|
||||
{
|
||||
// TODO(Ed): Lift this.
|
||||
Context* ctx = _ctx;
|
||||
CodeClass result = InvalidCode;
|
||||
LexedInfo lexed = struct_zero(LexedInfo);
|
||||
internal b32 parse_base_begin(Context* ctx, Str def, ParseInfo* info, char const* function_name) {
|
||||
if (ctx == nullptr || info == nullptr) GEN_FATAL("parse base: null context or info");
|
||||
|
||||
ctx->parser = struct_zero(ParseContext);
|
||||
if (check_parse_args(def) == false)
|
||||
goto done;
|
||||
|
||||
lexed = lex(ctx, def);
|
||||
ctx->parser.tokens = lexed.tokens;
|
||||
if (lexed.messages != nullptr || ctx->parser.tokens.num == 0) {
|
||||
if (lexed.messages != nullptr && lexed.messages->content.Ptr != nullptr)
|
||||
parser_record_failure(ctx, lexed.messages->content);
|
||||
else
|
||||
parser_record_failure(ctx, txt("parse: lex produced no tokens"));
|
||||
goto done;
|
||||
info[0] = struct_zero(ParseInfo);
|
||||
info->result = Code_Invalid;
|
||||
ctx->parser = struct_zero(ParseContext);
|
||||
if (_check_parse_args(ctx, def, function_name) == false) {
|
||||
info->messages = ctx->parser.messages;
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
ParseStackNode scope = NullScope;
|
||||
parser_push(& ctx->parser, & scope);
|
||||
result = (CodeClass) parse_class_struct( ctx, Tok_Decl_Class, parser_not_inplace_def );
|
||||
parser_pop(& ctx->parser);
|
||||
info->lexed = lex(ctx, def);
|
||||
ctx->parser.lexed_messages = info->lexed.messages;
|
||||
if (info->lexed.tokens.num == 0) {
|
||||
info->messages = ctx->parser.messages;
|
||||
return false;
|
||||
}
|
||||
done:
|
||||
return result;
|
||||
|
||||
ctx->parser.tokens = info->lexed.tokens;
|
||||
return true;
|
||||
}
|
||||
|
||||
CodeConstructor parse_constructor(Str def )
|
||||
{
|
||||
// TODO(Ed): Lift this.
|
||||
Context* ctx = _ctx;
|
||||
CodeConstructor result = InvalidCode;
|
||||
LexedInfo lexed = struct_zero(LexedInfo);
|
||||
|
||||
ctx->parser = struct_zero(ParseContext);
|
||||
if (check_parse_args(def) == false)
|
||||
goto done;
|
||||
|
||||
lexed = lex(ctx, def);
|
||||
ctx->parser.tokens = lexed.tokens;
|
||||
if (lexed.messages != nullptr || ctx->parser.tokens.num == 0) {
|
||||
if (lexed.messages != nullptr && lexed.messages->content.Ptr != nullptr)
|
||||
parser_record_failure(ctx, lexed.messages->content);
|
||||
else
|
||||
parser_record_failure(ctx, txt("parse: lex produced no tokens"));
|
||||
goto done;
|
||||
void parse_class_base(Context* ctx, Str def, ParseInfo* info) {
|
||||
CodeClass result = InvalidCode;
|
||||
if (parse_base_begin(ctx, def, info, "parse_class") == false) return;
|
||||
/*Parse*/ {
|
||||
ParseStackNode scope = NullScope; parser_push(& ctx->parser, & scope);
|
||||
result = (CodeClass) parse_class_struct( ctx, Tok_Decl_Class, parser_not_inplace_def );
|
||||
parser_pop(& ctx->parser);
|
||||
}
|
||||
info->result = cast(Code, result);
|
||||
info->messages = ctx->parser.messages;
|
||||
}
|
||||
|
||||
{
|
||||
ParseStackNode scope = NullScope;
|
||||
parser_push(& ctx->parser, & scope);
|
||||
CodeClass parse_class(Str def, Opts_parse opts) {
|
||||
Opts_parse resolved = get_optional(opts); Context* ctx = resolved.ctx;
|
||||
if (ctx == nullptr) ctx = _ctx; if (ctx == nullptr) GEN_FATAL("parse_class: no context");
|
||||
ParseInfo* info = resolved.info; if (info == nullptr) info = & ctx->parse_info;
|
||||
parse_class_base(ctx, def, info); return cast(CodeClass, info->result);
|
||||
}
|
||||
|
||||
// TODO(Ed): Constructors can have prefix attributes
|
||||
void parse_constructor_base(Context* ctx, Str def, ParseInfo* info)
|
||||
{
|
||||
CodeConstructor result = InvalidCode;
|
||||
if (parse_base_begin(ctx, def, info, "parse_constructor") == false) return;
|
||||
/*Parse*/ {
|
||||
ParseStackNode scope = NullScope; parser_push(& ctx->parser, & scope);
|
||||
|
||||
CodeSpecifiers specifiers = NullCode;
|
||||
Specifier specs_found[ 16 ] = { Spec_NumSpecifiers };
|
||||
s32 NumSpecifiers = 0;
|
||||
|
||||
while ( left && tok_is_specifier(currtok) )
|
||||
{
|
||||
Specifier spec = str_to_specifier( currtok.Text );
|
||||
|
||||
b32 ignore_spec = false;
|
||||
|
||||
switch ( spec )
|
||||
// TODO(Ed): Constructors can have prefix attributes
|
||||
CodeSpecifiers specifiers = NullCode;
|
||||
Specifier specs_found[ 16 ] = { Spec_NumSpecifiers };
|
||||
s32 NumSpecifiers = 0;
|
||||
while ( left && tok_is_specifier(currtok) )
|
||||
{
|
||||
b32 ignore_spec = false;
|
||||
Specifier spec = str_to_specifier( currtok.Text );
|
||||
switch ( spec ) {
|
||||
case Spec_Constexpr :
|
||||
case Spec_Explicit:
|
||||
case Spec_Inline :
|
||||
@@ -126,227 +107,160 @@ CodeConstructor parse_constructor(Str def )
|
||||
default :
|
||||
log_failure( "Invalid specifier %s for variable\n%S", spec_to_str( spec ), parser_to_strbuilder(& ctx->parser, ctx->Allocator_Temp) );
|
||||
parser_pop(& ctx->parser);
|
||||
goto done;
|
||||
info->result = cast(Code, result);
|
||||
info->messages = ctx->parser.messages;
|
||||
return;
|
||||
}
|
||||
|
||||
// Every specifier after would be considered part of the type type signature
|
||||
if (ignore_spec) break;
|
||||
|
||||
specs_found[ NumSpecifiers ] = spec;
|
||||
++ NumSpecifiers;
|
||||
eat( currtok.Type );
|
||||
}
|
||||
|
||||
// Every specifier after would be considered part of the type type signature
|
||||
if (ignore_spec)
|
||||
break;
|
||||
|
||||
specs_found[ NumSpecifiers ] = spec;
|
||||
NumSpecifiers++;
|
||||
eat( currtok.Type );
|
||||
if ( NumSpecifiers ) {
|
||||
specifiers = def_specifiers_arr( NumSpecifiers, specs_found );
|
||||
// <specifiers> ...
|
||||
}
|
||||
result = parser_parse_constructor(ctx, specifiers);
|
||||
parser_pop(& ctx->parser);
|
||||
}
|
||||
|
||||
if ( NumSpecifiers ) {
|
||||
specifiers = def_specifiers_arr( NumSpecifiers, specs_found );
|
||||
// <specifiers> ...
|
||||
}
|
||||
|
||||
result = parser_parse_constructor(ctx, specifiers);
|
||||
parser_pop(& ctx->parser);
|
||||
}
|
||||
done:
|
||||
return result;
|
||||
info->result = cast(Code, result);
|
||||
info->messages = ctx->parser.messages;
|
||||
}
|
||||
|
||||
CodeDefine parse_define( Str def )
|
||||
{
|
||||
// TODO(Ed): Lift this.
|
||||
Context* ctx = _ctx;
|
||||
CodeConstructor parse_constructor(Str def, Opts_parse opts) {
|
||||
Opts_parse resolved = get_optional(opts); Context* ctx = resolved.ctx;
|
||||
if (ctx == nullptr) ctx = _ctx; if (ctx == nullptr) GEN_FATAL("parse_constructor: no context");
|
||||
ParseInfo* info = resolved.info; if (info == nullptr) info = & ctx->parse_info;
|
||||
parse_constructor_base(ctx, def, info); return cast(CodeConstructor, info->result);
|
||||
}
|
||||
|
||||
void parse_define_base(Context* ctx, Str def, ParseInfo* info) {
|
||||
CodeDefine result = InvalidCode;
|
||||
LexedInfo lexed = struct_zero(LexedInfo);
|
||||
|
||||
ctx->parser = struct_zero(ParseContext);
|
||||
if (check_parse_args(def) == false)
|
||||
goto done;
|
||||
|
||||
lexed = lex(ctx, def);
|
||||
ctx->parser.tokens = lexed.tokens;
|
||||
if (lexed.messages != nullptr || ctx->parser.tokens.num == 0) {
|
||||
if (lexed.messages != nullptr && lexed.messages->content.Ptr != nullptr)
|
||||
parser_record_failure(ctx, lexed.messages->content);
|
||||
else
|
||||
parser_record_failure(ctx, txt("parse: lex produced no tokens"));
|
||||
goto done;
|
||||
if (parse_base_begin(ctx, def, info, "parse_define") == false) return;
|
||||
/*Parse*/ {
|
||||
ParseStackNode scope = NullScope; parser_push(& ctx->parser, & scope);
|
||||
result = parser_parse_define(ctx);
|
||||
parser_pop(& ctx->parser);
|
||||
}
|
||||
|
||||
{
|
||||
ParseStackNode scope = NullScope;
|
||||
parser_push(& ctx->parser, & scope);
|
||||
result = parser_parse_define(ctx);
|
||||
parser_pop(& ctx->parser);
|
||||
}
|
||||
done:
|
||||
return result;
|
||||
info->result = cast(Code, result);
|
||||
info->messages = ctx->parser.messages;
|
||||
}
|
||||
|
||||
CodeDestructor parse_destructor( Str def )
|
||||
{
|
||||
// TODO(Ed): Lift this.
|
||||
Context* ctx = _ctx;
|
||||
CodeDefine parse_define(Str def, Opts_parse opts) {
|
||||
Opts_parse resolved = get_optional(opts); Context* ctx = resolved.ctx;
|
||||
if (ctx == nullptr) ctx = _ctx; if (ctx == nullptr) GEN_FATAL("parse_define: no context");
|
||||
ParseInfo* info = resolved.info; if (info == nullptr) info = & ctx->parse_info;
|
||||
parse_define_base(ctx, def, info); return cast(CodeDefine, info->result);
|
||||
}
|
||||
|
||||
void parse_destructor_base(Context* ctx, Str def, ParseInfo* info) {
|
||||
CodeDestructor result = InvalidCode;
|
||||
LexedInfo lexed = struct_zero(LexedInfo);
|
||||
|
||||
ctx->parser = struct_zero(ParseContext);
|
||||
if (check_parse_args(def) == false)
|
||||
goto done;
|
||||
|
||||
lexed = lex(ctx, def);
|
||||
ctx->parser.tokens = lexed.tokens;
|
||||
if (lexed.messages != nullptr || ctx->parser.tokens.num == 0) {
|
||||
if (lexed.messages != nullptr && lexed.messages->content.Ptr != nullptr)
|
||||
parser_record_failure(ctx, lexed.messages->content);
|
||||
else
|
||||
parser_record_failure(ctx, txt("parse: lex produced no tokens"));
|
||||
goto done;
|
||||
}
|
||||
if (parse_base_begin(ctx, def, info, "parse_destructor") == false) return;
|
||||
|
||||
// TODO(Ed): Destructors can have prefix attributes
|
||||
// TODO(Ed): Destructors can have virtual
|
||||
|
||||
result = parser_parse_destructor(ctx, NullCode);
|
||||
done:
|
||||
return result;
|
||||
info->result = cast(Code, result);
|
||||
info->messages = ctx->parser.messages;
|
||||
}
|
||||
|
||||
CodeEnum parse_enum( Str def )
|
||||
{
|
||||
// TODO(Ed): Lift this.
|
||||
Context* ctx = _ctx;
|
||||
CodeDestructor parse_destructor(Str def, Opts_parse opts) {
|
||||
Opts_parse resolved = get_optional(opts); Context* ctx = resolved.ctx;
|
||||
if (ctx == nullptr) ctx = _ctx; if (ctx == nullptr) GEN_FATAL("parse_destructor: no context");
|
||||
ParseInfo* info = resolved.info; if (info == nullptr) info = & ctx->parse_info;
|
||||
parse_destructor_base(ctx, def, info); return cast(CodeDestructor, info->result);
|
||||
}
|
||||
|
||||
void parse_enum_base(Context* ctx, Str def, ParseInfo* info) {
|
||||
CodeEnum result = InvalidCode;
|
||||
LexedInfo lexed = struct_zero(LexedInfo);
|
||||
|
||||
ctx->parser = struct_zero(ParseContext);
|
||||
if (check_parse_args(def) == false)
|
||||
goto done;
|
||||
|
||||
lexed = lex(ctx, def);
|
||||
ctx->parser.tokens = lexed.tokens;
|
||||
if (lexed.messages != nullptr || ctx->parser.tokens.num == 0) {
|
||||
if (lexed.messages != nullptr && lexed.messages->content.Ptr != nullptr)
|
||||
parser_record_failure(ctx, lexed.messages->content);
|
||||
else
|
||||
parser_record_failure(ctx, txt("parse: lex produced no tokens"));
|
||||
goto done;
|
||||
}
|
||||
if (parse_base_begin(ctx, def, info, "parse_enum") == false) return;
|
||||
|
||||
result = parser_parse_enum(ctx, parser_not_inplace_def);
|
||||
done:
|
||||
return result;
|
||||
info->result = cast(Code, result);
|
||||
info->messages = ctx->parser.messages;
|
||||
}
|
||||
|
||||
CodeBody parse_export_body( Str def )
|
||||
{
|
||||
// TODO(Ed): Lift this.
|
||||
Context* ctx = _ctx;
|
||||
CodeEnum parse_enum(Str def, Opts_parse opts) {
|
||||
Opts_parse resolved = get_optional(opts); Context* ctx = resolved.ctx;
|
||||
if (ctx == nullptr) ctx = _ctx; if (ctx == nullptr) GEN_FATAL("parse_enum: no context");
|
||||
ParseInfo* info = resolved.info; if (info == nullptr) info = & ctx->parse_info;
|
||||
parse_enum_base(ctx, def, info); return cast(CodeEnum, info->result);
|
||||
}
|
||||
|
||||
void parse_export_body_base(Context* ctx, Str def, ParseInfo* info) {
|
||||
CodeBody result = InvalidCode;
|
||||
LexedInfo lexed = struct_zero(LexedInfo);
|
||||
|
||||
ctx->parser = struct_zero(ParseContext);
|
||||
if (check_parse_args(def) == false)
|
||||
goto done;
|
||||
|
||||
lexed = lex(ctx, def);
|
||||
ctx->parser.tokens = lexed.tokens;
|
||||
if (lexed.messages != nullptr || ctx->parser.tokens.num == 0) {
|
||||
if (lexed.messages != nullptr && lexed.messages->content.Ptr != nullptr)
|
||||
parser_record_failure(ctx, lexed.messages->content);
|
||||
else
|
||||
parser_record_failure(ctx, txt("parse: lex produced no tokens"));
|
||||
goto done;
|
||||
}
|
||||
if (parse_base_begin(ctx, def, info, "parse_export_body") == false) return;
|
||||
|
||||
result = parser_parse_export_body(ctx);
|
||||
done:
|
||||
return result;
|
||||
info->result = cast(Code, result);
|
||||
info->messages = ctx->parser.messages;
|
||||
}
|
||||
|
||||
CodeExtern parse_extern_link( Str def )
|
||||
{
|
||||
// TODO(Ed): Lift this.
|
||||
Context* ctx = _ctx;
|
||||
CodeBody parse_export_body(Str def, Opts_parse opts) {
|
||||
Opts_parse resolved = get_optional(opts); Context* ctx = resolved.ctx;
|
||||
if (ctx == nullptr) ctx = _ctx; if (ctx == nullptr) GEN_FATAL("parse_export_body: no context");
|
||||
ParseInfo* info = resolved.info; if (info == nullptr) info = & ctx->parse_info;
|
||||
parse_export_body_base(ctx, def, info); return cast(CodeBody, info->result);
|
||||
}
|
||||
|
||||
void parse_extern_link_base(Context* ctx, Str def, ParseInfo* info) {
|
||||
CodeExtern result = InvalidCode;
|
||||
LexedInfo lexed = struct_zero(LexedInfo);
|
||||
|
||||
ctx->parser = struct_zero(ParseContext);
|
||||
if (check_parse_args(def) == false)
|
||||
goto done;
|
||||
|
||||
lexed = lex(ctx, def);
|
||||
ctx->parser.tokens = lexed.tokens;
|
||||
if (lexed.messages != nullptr || ctx->parser.tokens.num == 0) {
|
||||
if (lexed.messages != nullptr && lexed.messages->content.Ptr != nullptr)
|
||||
parser_record_failure(ctx, lexed.messages->content);
|
||||
else
|
||||
parser_record_failure(ctx, txt("parse: lex produced no tokens"));
|
||||
goto done;
|
||||
}
|
||||
if (parse_base_begin(ctx, def, info, "parse_extern_link") == false) return;
|
||||
|
||||
result = parser_parse_extern_link(ctx);
|
||||
done:
|
||||
return result;
|
||||
info->result = cast(Code, result);
|
||||
info->messages = ctx->parser.messages;
|
||||
}
|
||||
|
||||
CodeFriend parse_friend( Str def )
|
||||
{
|
||||
// TODO(Ed): Lift this.
|
||||
Context* ctx = _ctx;
|
||||
CodeExtern parse_extern_link(Str def, Opts_parse opts) {
|
||||
Opts_parse resolved = get_optional(opts); Context* ctx = resolved.ctx;
|
||||
if (ctx == nullptr) ctx = _ctx; if (ctx == nullptr) GEN_FATAL("parse_extern_link: no context");
|
||||
ParseInfo* info = resolved.info; if (info == nullptr) info = & ctx->parse_info;
|
||||
parse_extern_link_base(ctx, def, info); return cast(CodeExtern, info->result);
|
||||
}
|
||||
|
||||
void parse_friend_base(Context* ctx, Str def, ParseInfo* info) {
|
||||
CodeFriend result = InvalidCode;
|
||||
LexedInfo lexed = struct_zero(LexedInfo);
|
||||
|
||||
ctx->parser = struct_zero(ParseContext);
|
||||
if (check_parse_args(def) == false)
|
||||
goto done;
|
||||
|
||||
lexed = lex(ctx, def);
|
||||
ctx->parser.tokens = lexed.tokens;
|
||||
if (lexed.messages != nullptr || ctx->parser.tokens.num == 0) {
|
||||
if (lexed.messages != nullptr && lexed.messages->content.Ptr != nullptr)
|
||||
parser_record_failure(ctx, lexed.messages->content);
|
||||
else
|
||||
parser_record_failure(ctx, txt("parse: lex produced no tokens"));
|
||||
goto done;
|
||||
}
|
||||
if (parse_base_begin(ctx, def, info, "parse_friend") == false) return;
|
||||
|
||||
result = parser_parse_friend(ctx);
|
||||
done:
|
||||
return result;
|
||||
info->result = cast(Code, result);
|
||||
info->messages = ctx->parser.messages;
|
||||
}
|
||||
|
||||
CodeFn parse_function( Str def )
|
||||
{
|
||||
// TODO(Ed): Lift this.
|
||||
Context* ctx = _ctx;
|
||||
CodeFn result = InvalidCode;
|
||||
LexedInfo lexed = struct_zero(LexedInfo);
|
||||
CodeFriend parse_friend(Str def, Opts_parse opts) {
|
||||
Opts_parse resolved = get_optional(opts); Context* ctx = resolved.ctx;
|
||||
if (ctx == nullptr) ctx = _ctx; if (ctx == nullptr) GEN_FATAL("parse_friend: no context");
|
||||
ParseInfo* info = resolved.info; if (info == nullptr) info = & ctx->parse_info;
|
||||
parse_friend_base(ctx, def, info); return cast(CodeFriend, info->result);
|
||||
}
|
||||
|
||||
ctx->parser = struct_zero(ParseContext);
|
||||
if (check_parse_args(def) == false)
|
||||
goto done;
|
||||
|
||||
lexed = lex(ctx, def);
|
||||
ctx->parser.tokens = lexed.tokens;
|
||||
if (lexed.messages != nullptr || ctx->parser.tokens.num == 0) {
|
||||
if (lexed.messages != nullptr && lexed.messages->content.Ptr != nullptr)
|
||||
parser_record_failure(ctx, lexed.messages->content);
|
||||
else
|
||||
parser_record_failure(ctx, txt("parse: lex produced no tokens"));
|
||||
goto done;
|
||||
}
|
||||
void parse_function_base(Context* ctx, Str def, ParseInfo* info) {
|
||||
CodeFn result = InvalidCode;
|
||||
if (parse_base_begin(ctx, def, info, "parse_function") == false) return;
|
||||
|
||||
result = (CodeFn) parser_parse_function(ctx);
|
||||
done:
|
||||
return result;
|
||||
info->result = cast(Code, result);
|
||||
info->messages = ctx->parser.messages;
|
||||
}
|
||||
|
||||
CodeFn parse_function(Str def, Opts_parse opts) {
|
||||
Opts_parse resolved = get_optional(opts);
|
||||
Context* ctx = resolved.ctx;
|
||||
if (ctx == nullptr) ctx = _ctx; if (ctx == nullptr) GEN_FATAL("parse_function: no context");
|
||||
ParseInfo* info = resolved.info; if (info == nullptr) info = & ctx->parse_info;
|
||||
parse_function_base(ctx, def, info); return cast(CodeFn, info->result);
|
||||
}
|
||||
|
||||
void parse_global_body_base( Context* ctx, Str def, ParseInfo* info )
|
||||
{
|
||||
LexedInfo lexed;
|
||||
CodeBody body;
|
||||
|
||||
if ( ctx == nullptr || info == nullptr )
|
||||
GEN_FATAL( "parse_global_body_base: null context or info" );
|
||||
LexedInfo lexed; CodeBody body;
|
||||
if ( ctx == nullptr || info == nullptr ) GEN_FATAL( "parse_global_body_base: null context or info" );
|
||||
|
||||
info[0] = struct_zero( ParseInfo );
|
||||
lexed = struct_zero( LexedInfo );
|
||||
@@ -362,6 +276,7 @@ void parse_global_body_base( Context* ctx, Str def, ParseInfo* info )
|
||||
|
||||
lexed = lex( ctx, def );
|
||||
info->lexed = lexed;
|
||||
ctx->parser.lexed_messages = lexed.messages;
|
||||
if ( lexed.tokens.num == 0 ) {
|
||||
info->result = cast( Code, body );
|
||||
info->messages = ctx->parser.messages;
|
||||
@@ -378,286 +293,179 @@ void parse_global_body_base( Context* ctx, Str def, ParseInfo* info )
|
||||
info->messages = ctx->parser.messages;
|
||||
}
|
||||
|
||||
CodeBody parse_global_body( Str def, Opts_parse_global_body opts ) {
|
||||
Opts_parse_global_body resolved = get_optional( opts );
|
||||
Context* ctx = resolved.ctx;
|
||||
ParseInfo* info;
|
||||
|
||||
if ( ctx == nullptr ) ctx = _ctx;
|
||||
if ( ctx == nullptr ) GEN_FATAL( "parse_global_body: no context" );
|
||||
info = resolved.info; if ( info == nullptr ) info = & ctx->parse_info;
|
||||
|
||||
parse_global_body_base( ctx, def, info );
|
||||
return cast( CodeBody, info->result );
|
||||
CodeBody parse_global_body( Str def, Opts_parse opts ) {
|
||||
Opts_parse resolved = get_optional(opts); Context* ctx = resolved.ctx;
|
||||
if ( ctx == nullptr ) ctx = _ctx; if ( ctx == nullptr ) GEN_FATAL( "parse_global_body: no context" );
|
||||
ParseInfo* info = resolved.info; if ( info == nullptr ) info = & ctx->parse_info;
|
||||
parse_global_body_base( ctx, def, info ); return cast( CodeBody, info->result );
|
||||
}
|
||||
|
||||
CodeNS parse_namespace( Str def )
|
||||
{
|
||||
// TODO(Ed): Lift this.
|
||||
Context* ctx = _ctx;
|
||||
CodeNS result = InvalidCode;
|
||||
LexedInfo lexed = struct_zero(LexedInfo);
|
||||
|
||||
ctx->parser = struct_zero(ParseContext);
|
||||
if (check_parse_args(def) == false)
|
||||
goto done;
|
||||
|
||||
lexed = lex(ctx, def);
|
||||
ctx->parser.tokens = lexed.tokens;
|
||||
if (lexed.messages != nullptr || ctx->parser.tokens.num == 0) {
|
||||
if (lexed.messages != nullptr && lexed.messages->content.Ptr != nullptr)
|
||||
parser_record_failure(ctx, lexed.messages->content);
|
||||
else
|
||||
parser_record_failure(ctx, txt("parse: lex produced no tokens"));
|
||||
goto done;
|
||||
}
|
||||
void parse_namespace_base(Context* ctx, Str def, ParseInfo* info) {
|
||||
CodeNS result = InvalidCode;
|
||||
if (parse_base_begin(ctx, def, info, "parse_namespace") == false) return;
|
||||
|
||||
result = parser_parse_namespace(ctx);
|
||||
done:
|
||||
return result;
|
||||
info->result = cast(Code, result);
|
||||
info->messages = ctx->parser.messages;
|
||||
}
|
||||
|
||||
CodeOperator parse_operator( Str def )
|
||||
{
|
||||
// TODO(Ed): Lift this.
|
||||
Context* ctx = _ctx;
|
||||
CodeNS parse_namespace(Str def, Opts_parse opts) {
|
||||
Opts_parse resolved = get_optional(opts); Context* ctx = resolved.ctx;
|
||||
if (ctx == nullptr) ctx = _ctx; if (ctx == nullptr) GEN_FATAL("parse_namespace: no context");
|
||||
ParseInfo* info = resolved.info; if (info == nullptr) info = &ctx->parse_info;
|
||||
parse_namespace_base(ctx, def, info); return cast(CodeNS, info->result);
|
||||
}
|
||||
|
||||
void parse_operator_base(Context* ctx, Str def, ParseInfo* info) {
|
||||
CodeOperator result = InvalidCode;
|
||||
LexedInfo lexed = struct_zero(LexedInfo);
|
||||
|
||||
ctx->parser = struct_zero(ParseContext);
|
||||
if (check_parse_args(def) == false)
|
||||
goto done;
|
||||
|
||||
lexed = lex(ctx, def);
|
||||
ctx->parser.tokens = lexed.tokens;
|
||||
if (lexed.messages != nullptr || ctx->parser.tokens.num == 0) {
|
||||
if (lexed.messages != nullptr && lexed.messages->content.Ptr != nullptr)
|
||||
parser_record_failure(ctx, lexed.messages->content);
|
||||
else
|
||||
parser_record_failure(ctx, txt("parse: lex produced no tokens"));
|
||||
goto done;
|
||||
}
|
||||
if (parse_base_begin(ctx, def, info, "parse_operator") == false) return;
|
||||
|
||||
result = (CodeOperator) parser_parse_operator(ctx);
|
||||
done:
|
||||
return result;
|
||||
info->result = cast(Code, result);
|
||||
info->messages = ctx->parser.messages;
|
||||
}
|
||||
|
||||
CodeOpCast parse_operator_cast( Str def )
|
||||
{
|
||||
// TODO(Ed): Lift this.
|
||||
Context* ctx = _ctx;
|
||||
CodeOperator parse_operator(Str def, Opts_parse opts) {
|
||||
Opts_parse resolved = get_optional(opts); Context* ctx = resolved.ctx; ParseInfo* info;
|
||||
if (ctx == nullptr) ctx = _ctx; if (ctx == nullptr) GEN_FATAL("parse_operator: no context");
|
||||
info = resolved.info; if (info == nullptr) info = &ctx->parse_info;
|
||||
parse_operator_base(ctx, def, info); return cast(CodeOperator, info->result);
|
||||
}
|
||||
|
||||
void parse_operator_cast_base(Context* ctx, Str def, ParseInfo* info) {
|
||||
CodeOpCast result = InvalidCode;
|
||||
LexedInfo lexed = struct_zero(LexedInfo);
|
||||
|
||||
ctx->parser = struct_zero(ParseContext);
|
||||
if (check_parse_args(def) == false)
|
||||
goto done;
|
||||
|
||||
lexed = lex(ctx, def);
|
||||
ctx->parser.tokens = lexed.tokens;
|
||||
if (lexed.messages != nullptr || ctx->parser.tokens.num == 0) {
|
||||
if (lexed.messages != nullptr && lexed.messages->content.Ptr != nullptr)
|
||||
parser_record_failure(ctx, lexed.messages->content);
|
||||
else
|
||||
parser_record_failure(ctx, txt("parse: lex produced no tokens"));
|
||||
goto done;
|
||||
}
|
||||
if (parse_base_begin(ctx, def, info, "parse_operator_cast") == false) return;
|
||||
|
||||
result = parser_parse_operator_cast(ctx, NullCode);
|
||||
done:
|
||||
return result;
|
||||
info->result = cast(Code, result);
|
||||
info->messages = ctx->parser.messages;
|
||||
}
|
||||
|
||||
CodeStruct parse_struct( Str def )
|
||||
{
|
||||
// TODO(Ed): Lift this.
|
||||
Context* ctx = _ctx;
|
||||
CodeOpCast parse_operator_cast(Str def, Opts_parse opts) {
|
||||
Opts_parse resolved = get_optional(opts); Context* ctx = resolved.ctx; ParseInfo* info;
|
||||
if (ctx == nullptr) ctx = _ctx; if (ctx == nullptr) GEN_FATAL("parse_operator_cast: no context");
|
||||
info = resolved.info; if (info == nullptr) info = &ctx->parse_info;
|
||||
parse_operator_cast_base(ctx, def, info); return cast(CodeOpCast, info->result);
|
||||
}
|
||||
|
||||
void parse_struct_base(Context* ctx, Str def, ParseInfo* info) {
|
||||
CodeStruct result = InvalidCode;
|
||||
LexedInfo lexed = struct_zero(LexedInfo);
|
||||
|
||||
ctx->parser = struct_zero(ParseContext);
|
||||
if (check_parse_args(def) == false)
|
||||
goto done;
|
||||
|
||||
lexed = lex(ctx, def);
|
||||
ctx->parser.tokens = lexed.tokens;
|
||||
if (lexed.messages != nullptr || ctx->parser.tokens.num == 0) {
|
||||
if (lexed.messages != nullptr && lexed.messages->content.Ptr != nullptr)
|
||||
parser_record_failure(ctx, lexed.messages->content);
|
||||
else
|
||||
parser_record_failure(ctx, txt("parse: lex produced no tokens"));
|
||||
goto done;
|
||||
if (parse_base_begin(ctx, def, info, "parse_struct") == false) return;
|
||||
/*Parse*/ {
|
||||
ParseStackNode scope = NullScope;
|
||||
parser_push(& ctx->parser, & scope);
|
||||
result = (CodeStruct) parse_class_struct( ctx, Tok_Decl_Struct, parser_not_inplace_def );
|
||||
parser_pop(& ctx->parser);
|
||||
}
|
||||
|
||||
{
|
||||
ParseStackNode scope = NullScope;
|
||||
parser_push(& ctx->parser, & scope);
|
||||
result = (CodeStruct) parse_class_struct( ctx, Tok_Decl_Struct, parser_not_inplace_def );
|
||||
parser_pop(& ctx->parser);
|
||||
}
|
||||
done:
|
||||
return result;
|
||||
info->result = cast(Code, result);
|
||||
info->messages = ctx->parser.messages;
|
||||
}
|
||||
|
||||
CodeTemplate parse_template( Str def )
|
||||
{
|
||||
// TODO(Ed): Lift this.
|
||||
Context* ctx = _ctx;
|
||||
CodeStruct parse_struct(Str def, Opts_parse opts) {
|
||||
Opts_parse resolved = get_optional(opts); Context* ctx = resolved.ctx; ParseInfo* info;
|
||||
if (ctx == nullptr) ctx = _ctx; if (ctx == nullptr) GEN_FATAL("parse_struct: no context");
|
||||
info = resolved.info; if (info == nullptr) info = &ctx->parse_info;
|
||||
parse_struct_base(ctx, def, info); return cast(CodeStruct, info->result);
|
||||
}
|
||||
|
||||
void parse_template_base(Context* ctx, Str def, ParseInfo* info) {
|
||||
CodeTemplate result = InvalidCode;
|
||||
LexedInfo lexed = struct_zero(LexedInfo);
|
||||
|
||||
ctx->parser = struct_zero(ParseContext);
|
||||
if (check_parse_args(def) == false)
|
||||
goto done;
|
||||
|
||||
lexed = lex(ctx, def);
|
||||
ctx->parser.tokens = lexed.tokens;
|
||||
if (lexed.messages != nullptr || ctx->parser.tokens.num == 0) {
|
||||
if (lexed.messages != nullptr && lexed.messages->content.Ptr != nullptr)
|
||||
parser_record_failure(ctx, lexed.messages->content);
|
||||
else
|
||||
parser_record_failure(ctx, txt("parse: lex produced no tokens"));
|
||||
goto done;
|
||||
}
|
||||
if (parse_base_begin(ctx, def, info, "parse_template") == false) return;
|
||||
|
||||
result = parser_parse_template(ctx);
|
||||
done:
|
||||
return result;
|
||||
info->result = cast(Code, result);
|
||||
info->messages = ctx->parser.messages;
|
||||
}
|
||||
|
||||
CodeTypename parse_type( Str def )
|
||||
{
|
||||
// TODO(Ed): Lift this.
|
||||
Context* ctx = _ctx;
|
||||
CodeTemplate parse_template(Str def, Opts_parse opts) {
|
||||
Opts_parse resolved = get_optional(opts); Context* ctx = resolved.ctx; ParseInfo* info;
|
||||
if (ctx == nullptr) ctx = _ctx; if (ctx == nullptr) GEN_FATAL("parse_template: no context");
|
||||
info = resolved.info; if (info == nullptr) info = &ctx->parse_info;
|
||||
parse_template_base(ctx, def, info); return cast(CodeTemplate, info->result);
|
||||
}
|
||||
|
||||
void parse_type_base(Context* ctx, Str def, ParseInfo* info) {
|
||||
CodeTypename result = InvalidCode;
|
||||
LexedInfo lexed = struct_zero(LexedInfo);
|
||||
if (parse_base_begin(ctx, def, info, "parse_type") == false) return;
|
||||
|
||||
ctx->parser = struct_zero(ParseContext);
|
||||
if (check_parse_args(def) == false)
|
||||
goto done;
|
||||
|
||||
lexed = lex(ctx, def);
|
||||
ctx->parser.tokens = lexed.tokens;
|
||||
if (lexed.messages != nullptr || ctx->parser.tokens.num == 0) {
|
||||
if (lexed.messages != nullptr && lexed.messages->content.Ptr != nullptr)
|
||||
parser_record_failure(ctx, lexed.messages->content);
|
||||
else
|
||||
parser_record_failure(ctx, txt("parse: lex produced no tokens"));
|
||||
goto done;
|
||||
}
|
||||
|
||||
result = parser_parse_type( ctx, parser_not_from_template, nullptr);
|
||||
done:
|
||||
return result;
|
||||
result = parser_parse_type(ctx, parser_not_from_template, nullptr);
|
||||
info->result = cast(Code, result);
|
||||
info->messages = ctx->parser.messages;
|
||||
}
|
||||
|
||||
CodeTypedef parse_typedef( Str def )
|
||||
{
|
||||
// TODO(Ed): Lift this.
|
||||
Context* ctx = _ctx;
|
||||
CodeTypename parse_type(Str def, Opts_parse opts) {
|
||||
Opts_parse resolved = get_optional(opts); Context* ctx = resolved.ctx; ParseInfo* info;
|
||||
if (ctx == nullptr) ctx = _ctx; if (ctx == nullptr) GEN_FATAL("parse_type: no context");
|
||||
info = resolved.info; if (info == nullptr) info = &ctx->parse_info;
|
||||
parse_type_base(ctx, def, info); return cast(CodeTypename, info->result);
|
||||
}
|
||||
|
||||
void parse_typedef_base(Context* ctx, Str def, ParseInfo* info) {
|
||||
CodeTypedef result = InvalidCode;
|
||||
LexedInfo lexed = struct_zero(LexedInfo);
|
||||
|
||||
ctx->parser = struct_zero(ParseContext);
|
||||
if (check_parse_args(def) == false)
|
||||
goto done;
|
||||
|
||||
lexed = lex(ctx, def);
|
||||
ctx->parser.tokens = lexed.tokens;
|
||||
if (lexed.messages != nullptr || ctx->parser.tokens.num == 0) {
|
||||
if (lexed.messages != nullptr && lexed.messages->content.Ptr != nullptr)
|
||||
parser_record_failure(ctx, lexed.messages->content);
|
||||
else
|
||||
parser_record_failure(ctx, txt("parse: lex produced no tokens"));
|
||||
goto done;
|
||||
}
|
||||
if (parse_base_begin(ctx, def, info, "parse_typedef") == false) return;
|
||||
|
||||
result = parser_parse_typedef(ctx);
|
||||
done:
|
||||
return result;
|
||||
info->result = cast(Code, result);
|
||||
info->messages = ctx->parser.messages;
|
||||
}
|
||||
|
||||
CodeUnion parse_union( Str def )
|
||||
{
|
||||
// TODO(Ed): Lift this.
|
||||
Context* ctx = _ctx;
|
||||
CodeTypedef parse_typedef(Str def, Opts_parse opts) {
|
||||
Opts_parse resolved = get_optional(opts); Context* ctx = resolved.ctx; ParseInfo* info;
|
||||
if (ctx == nullptr) ctx = _ctx; if (ctx == nullptr) GEN_FATAL("parse_typedef: no context");
|
||||
info = resolved.info; if (info == nullptr) info = &ctx->parse_info;
|
||||
parse_typedef_base(ctx, def, info); return cast(CodeTypedef, info->result);
|
||||
}
|
||||
|
||||
void parse_union_base(Context* ctx, Str def, ParseInfo* info) {
|
||||
CodeUnion result = InvalidCode;
|
||||
LexedInfo lexed = struct_zero(LexedInfo);
|
||||
|
||||
ctx->parser = struct_zero(ParseContext);
|
||||
if (check_parse_args(def) == false)
|
||||
goto done;
|
||||
|
||||
lexed = lex(ctx, def);
|
||||
ctx->parser.tokens = lexed.tokens;
|
||||
if (lexed.messages != nullptr || ctx->parser.tokens.num == 0) {
|
||||
if (lexed.messages != nullptr && lexed.messages->content.Ptr != nullptr)
|
||||
parser_record_failure(ctx, lexed.messages->content);
|
||||
else
|
||||
parser_record_failure(ctx, txt("parse: lex produced no tokens"));
|
||||
goto done;
|
||||
}
|
||||
if (parse_base_begin(ctx, def, info, "parse_union") == false) return;
|
||||
|
||||
result = parser_parse_union(ctx, parser_not_inplace_def);
|
||||
done:
|
||||
return result;
|
||||
info->result = cast(Code, result);
|
||||
info->messages = ctx->parser.messages;
|
||||
}
|
||||
|
||||
CodeUsing parse_using( Str def )
|
||||
{
|
||||
// TODO(Ed): Lift this.
|
||||
Context* ctx = _ctx;
|
||||
CodeUnion parse_union(Str def, Opts_parse opts) {
|
||||
Opts_parse resolved = get_optional(opts); Context* ctx = resolved.ctx; ParseInfo* info;
|
||||
if (ctx == nullptr) ctx = _ctx; if (ctx == nullptr) GEN_FATAL("parse_union: no context");
|
||||
info = resolved.info; if (info == nullptr) info = &ctx->parse_info;
|
||||
parse_union_base(ctx, def, info); return cast(CodeUnion, info->result);
|
||||
}
|
||||
|
||||
void parse_using_base(Context* ctx, Str def, ParseInfo* info) {
|
||||
CodeUsing result = InvalidCode;
|
||||
LexedInfo lexed = struct_zero(LexedInfo);
|
||||
|
||||
ctx->parser = struct_zero(ParseContext);
|
||||
if (check_parse_args(def) == false)
|
||||
goto done;
|
||||
|
||||
lexed = lex(ctx, def);
|
||||
ctx->parser.tokens = lexed.tokens;
|
||||
if (lexed.messages != nullptr || ctx->parser.tokens.num == 0) {
|
||||
if (lexed.messages != nullptr && lexed.messages->content.Ptr != nullptr)
|
||||
parser_record_failure(ctx, lexed.messages->content);
|
||||
else
|
||||
parser_record_failure(ctx, txt("parse: lex produced no tokens"));
|
||||
goto done;
|
||||
}
|
||||
if (parse_base_begin(ctx, def, info, "parse_using") == false) return;
|
||||
|
||||
result = parser_parse_using(ctx);
|
||||
done:
|
||||
return result;
|
||||
info->result = cast(Code, result);
|
||||
info->messages = ctx->parser.messages;
|
||||
}
|
||||
|
||||
CodeVar parse_variable( Str def )
|
||||
{
|
||||
// TODO(Ed): Lift this.
|
||||
Context* ctx = _ctx;
|
||||
CodeVar result = InvalidCode;
|
||||
LexedInfo lexed = struct_zero(LexedInfo);
|
||||
CodeUsing parse_using(Str def, Opts_parse opts) {
|
||||
Opts_parse resolved = get_optional(opts); Context* ctx = resolved.ctx; ParseInfo* info;
|
||||
if (ctx == nullptr) ctx = _ctx; if (ctx == nullptr) GEN_FATAL("parse_using: no context");
|
||||
info = resolved.info; if (info == nullptr) info = &ctx->parse_info;
|
||||
parse_using_base(ctx, def, info); return cast(CodeUsing, info->result);
|
||||
}
|
||||
|
||||
ctx->parser = struct_zero(ParseContext);
|
||||
if (check_parse_args(def) == false)
|
||||
goto done;
|
||||
|
||||
lexed = lex(ctx, def);
|
||||
ctx->parser.tokens = lexed.tokens;
|
||||
if (lexed.messages != nullptr || ctx->parser.tokens.num == 0) {
|
||||
if (lexed.messages != nullptr && lexed.messages->content.Ptr != nullptr)
|
||||
parser_record_failure(ctx, lexed.messages->content);
|
||||
else
|
||||
parser_record_failure(ctx, txt("parse: lex produced no tokens"));
|
||||
goto done;
|
||||
}
|
||||
if (parser_slice_is_formatting_only(&ctx->parser)) {
|
||||
void parse_variable_base(Context* ctx, Str def, ParseInfo* info) {
|
||||
CodeVar result = InvalidCode;
|
||||
if (parse_base_begin(ctx, def, info, "parse_variable") == false) return;
|
||||
if (parser_slice_is_formatting_only(& ctx->parser)) {
|
||||
parser_record_failure(ctx, txt("parse_variable: only formatting tokens"));
|
||||
goto done;
|
||||
}
|
||||
else {
|
||||
result = parser_parse_variable(ctx);
|
||||
}
|
||||
info->result = cast(Code, result);
|
||||
info->messages = ctx->parser.messages;
|
||||
}
|
||||
|
||||
result = parser_parse_variable(ctx);
|
||||
done:
|
||||
return result;
|
||||
CodeVar parse_variable(Str def, Opts_parse opts) {
|
||||
Opts_parse resolved = get_optional(opts); Context* ctx = resolved.ctx; ParseInfo* info;
|
||||
if (ctx == nullptr) ctx = _ctx; if (ctx == nullptr) GEN_FATAL("parse_variable: no context");
|
||||
info = resolved.info; if (info == nullptr) info = &ctx->parse_info;
|
||||
parse_variable_base(ctx, def, info); return cast(CodeVar, info->result);
|
||||
}
|
||||
|
||||
// Undef helper macros
|
||||
|
||||
Reference in new issue
Block a user