Skip to content

Commit

Permalink
Turn __FUNCTION__ and __SCRIPT__ into keywords
Browse files Browse the repository at this point in the history
  • Loading branch information
positively-charged committed Feb 7, 2017
1 parent 8dc207f commit 4da7e63
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 99 deletions.
3 changes: 3 additions & 0 deletions doc/grammar.txt
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,9 @@ comment:
[/][*]([^*]*[*]+)+[/] // Multi-line comment.

keyword:
__function__
__namespace__
__script__
assert
auto
bool
Expand Down
8 changes: 8 additions & 0 deletions src/parse/expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,8 @@ void read_primary( struct parse* parse, struct expr_reading* reading ) {
read_paren( parse, reading );
break;
case TK_NAMESPACENAME:
case TK_FUNCTIONNAME:
case TK_SCRIPTNAME:
read_magic_id( parse, reading );
break;
default:
Expand Down Expand Up @@ -1333,6 +1335,12 @@ void read_magic_id( struct parse* parse, struct expr_reading* reading ) {
switch ( parse->tk ) {
case TK_NAMESPACENAME:
break;
case TK_FUNCTIONNAME:
magic_id->name = MAGICID_FUNCTION;
break;
case TK_SCRIPTNAME:
magic_id->name = MAGICID_SCRIPT;
break;
default:
UNREACHABLE();
}
Expand Down
2 changes: 2 additions & 0 deletions src/parse/phase.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ enum tk {
TK_STRICT,
// 150
TK_NAMESPACENAME,
TK_FUNCTIONNAME,
TK_SCRIPTNAME,

TK_TOTAL,

Expand Down
6 changes: 4 additions & 2 deletions src/parse/token/info.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,16 +173,18 @@ static struct token_info g_table[] = {
ENTRY( "strict", TKF_KEYWORD ),
// 150
ENTRY( "__NAMESPACE__", TKF_KEYWORD ),
ENTRY( "__FUNCTION__", TKF_KEYWORD ),
ENTRY( "__SCRIPT__", TKF_KEYWORD ),
};
#undef ENTRY

const struct token_info* p_get_token_info( enum tk tk ) {
STATIC_ASSERT( TK_TOTAL == 151 );
STATIC_ASSERT( TK_TOTAL == 153 );
return &g_table[ tk ];
}

void p_present_token( struct str* str, enum tk tk ) {
STATIC_ASSERT( TK_TOTAL == 151 );
STATIC_ASSERT( TK_TOTAL == 153 );
switch ( tk ) {
case TK_ID:
str_append( str,
Expand Down
2 changes: 2 additions & 0 deletions src/parse/token/user.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ void read_token_bcs( struct parse* parse ) {
const char* name;
enum tk tk;
} table[] = {
{ "__function__", TK_FUNCTIONNAME },
{ "__namespace__", TK_NAMESPACENAME },
{ "__script__", TK_SCRIPTNAME },
{ "assert", TK_ASSERT },
{ "auto", TK_AUTO },
{ "bool", TK_BOOL },
Expand Down
43 changes: 2 additions & 41 deletions src/semantic/dec.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,6 @@ struct builtin_aliases {
struct alias alias;
bool used;
} append;
struct {
struct alias alias;
struct object object;
} funcname;
};

struct builtin_script_aliases {
struct {
struct alias alias;
struct object object;
} script_id;
};

struct value_list {
Expand Down Expand Up @@ -266,8 +255,6 @@ static void test_script_param_list( struct semantic* semantic,
struct script* script );
static void test_script_body( struct semantic* semantic,
struct script* script );
static void init_builtin_script_aliases( struct semantic* semantic,
struct builtin_script_aliases* aliases, struct script* script );

void s_test_constant( struct semantic* semantic, struct constant* constant ) {
// Test expression.
Expand Down Expand Up @@ -2297,17 +2284,9 @@ void s_test_func_body( struct semantic* semantic, struct func* func ) {
// a link to a builtin namespace would be better.
void init_builtin_aliases( struct semantic* semantic, struct func* func,
struct builtin_aliases* aliases ) {
struct func_user* impl = func->impl;
// __FUNCTION__ is a string that is the name of the current function.
t_init_object( &aliases->funcname.object, NODE_FUNCNAME );
aliases->funcname.object.resolved = true;
struct alias* alias = &aliases->funcname.alias;
s_init_alias( alias );
alias->object.resolved = true;
alias->target = &aliases->funcname.object;
// append().
if ( func->msgbuild ) {
alias = &aliases->append.alias;
struct alias* alias = &aliases->append.alias;
s_init_alias( alias );
alias->object.resolved = true;
alias->target = &semantic->task->append_func->object;
Expand All @@ -2320,10 +2299,8 @@ void init_builtin_aliases( struct semantic* semantic, struct func* func,

void bind_builtin_aliases( struct semantic* semantic,
struct builtin_aliases* aliases ) {
struct name* name = t_extend_name( semantic->ns->body, "__function__" );
s_bind_local_name( semantic, name, &aliases->funcname.alias.object, true );
if ( aliases->append.used ) {
name = t_extend_name( semantic->ns->body, "append" );
struct name* name = t_extend_name( semantic->ns->body, "append" );
s_bind_local_name( semantic, name, &aliases->append.alias.object, true );
}
}
Expand Down Expand Up @@ -2437,8 +2414,6 @@ void test_script_param_list( struct semantic* semantic,

void test_script_body( struct semantic* semantic, struct script* script ) {
s_add_scope( semantic, true );
struct builtin_script_aliases aliases;
init_builtin_script_aliases( semantic, &aliases, script );
struct param* param = script->params;
while ( param ) {
if ( param->name ) {
Expand All @@ -2458,20 +2433,6 @@ void test_script_body( struct semantic* semantic, struct script* script ) {
s_pop_scope( semantic );
}

void init_builtin_script_aliases( struct semantic* semantic,
struct builtin_script_aliases* aliases, struct script* script ) {
// __SCRIPT__ is a string that contains either the name or number of the
// current script.
t_init_object( &aliases->script_id.object, NODE_SCRIPTID );
aliases->script_id.object.resolved = true;
struct alias* alias = &aliases->script_id.alias;
s_init_alias( alias );
alias->object.resolved = true;
alias->target = &aliases->script_id.object;
struct name* name = t_extend_name( semantic->ns->body, "__script__" );
s_bind_local_name( semantic, name, &aliases->script_id.alias.object, true );
}

void s_calc_var_size( struct var* var ) {
var->size = calc_size( var->dim, var->structure, var->ref );
}
Expand Down
88 changes: 35 additions & 53 deletions src/semantic/expr.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <string.h>

#include "parse/phase.h"
#include "codegen/phase.h"
#include "phase.h"

Expand Down Expand Up @@ -169,10 +170,6 @@ static void test_found_object( struct semantic* semantic,
static struct ref* find_map_ref( struct ref* ref,
struct structure* structure );
static struct ref* find_map_ref_struct( struct structure* structure );
static void test_funcname( struct semantic* semantic, struct expr_test* test,
struct result* result, struct name_usage* usage );
static void test_script_id( struct semantic* semantic, struct expr_test* test,
struct result* result, struct name_usage* usage );
static void select_object( struct semantic* semantic, struct expr_test* test,
struct result* result, struct object* object );
static void select_constant( struct semantic* semantic, struct expr_test* test,
Expand Down Expand Up @@ -2395,16 +2392,8 @@ void test_found_object( struct semantic* semantic, struct expr_test* test,
s_bail( semantic );
}
}
if ( object->node.type == NODE_FUNCNAME ) {
test_funcname( semantic, test, result, usage );
}
else if ( object->node.type == NODE_SCRIPTID ) {
test_script_id( semantic, test, result, usage );
}
else {
select_object( semantic, test, result, object );
usage->object = &object->node;
}
select_object( semantic, test, result, object );
usage->object = &object->node;
}

struct ref* find_map_ref( struct ref* ref, struct structure* structure ) {
Expand Down Expand Up @@ -2446,45 +2435,6 @@ struct ref* find_map_ref_struct( struct structure* structure ) {
return ref;
}

void test_funcname( struct semantic* semantic, struct expr_test* test,
struct result* result, struct name_usage* usage ) {
struct str name;
str_init( &name );
if ( semantic->func_test->func->name ) {
t_copy_name( semantic->func_test->func->name, false, &name );
}
else {
// TODO: Create a nicer name.
str_append( &name, "" );
}
struct indexed_string_usage* string_usage = t_alloc_indexed_string_usage();
string_usage->string = t_intern_string_copy( semantic->task,
name.value, name.length );
usage->object = &string_usage->node;
test_string_usage( semantic, test, result, string_usage );
str_deinit( &name );
}

void test_script_id( struct semantic* semantic, struct expr_test* test,
struct result* result, struct name_usage* usage ) {
struct str name;
str_init( &name );
if ( semantic->func_test->script->named_script ) {
struct indexed_string* string = t_lookup_string( semantic->task,
semantic->func_test->script->number->value );
str_append( &name, string->value );
}
else {
str_append_number( &name, semantic->func_test->script->number->value );
}
struct indexed_string_usage* string_usage = t_alloc_indexed_string_usage();
string_usage->string = t_intern_string_copy( semantic->task,
name.value, name.length );
usage->object = &string_usage->node;
test_string_usage( semantic, test, result, string_usage );
str_deinit( &name );
}

void select_object( struct semantic* semantic, struct expr_test* test,
struct result* result, struct object* object ) {
switch ( object->node.type ) {
Expand Down Expand Up @@ -3003,6 +2953,38 @@ void expand_magic_id( struct semantic* semantic, struct magic_id* magic_id ) {
t_copy_name( semantic->ns->name, true, &name );
}
break;
case MAGICID_FUNCTION:
if ( ! ( semantic->func_test && semantic->func_test->func ) ) {
s_diag( semantic, DIAG_POS_ERR, &magic_id->pos,
"using %s outside a function",
p_get_token_info( TK_FUNCTIONNAME )->shared_text );
s_bail( semantic );
}
if ( semantic->func_test->func->name ) {
t_copy_name( semantic->func_test->func->name, false, &name );
}
else {
// TODO: Create a nicer name.
str_append( &name, "" );
}
break;
case MAGICID_SCRIPT:
if ( ! ( semantic->func_test && semantic->func_test->script ) ) {
s_diag( semantic, DIAG_POS_ERR, &magic_id->pos,
"using %s outside a script",
p_get_token_info( TK_SCRIPTNAME )->shared_text );
s_bail( semantic );
}
if ( semantic->func_test->script->named_script ) {
struct indexed_string* string = t_lookup_string( semantic->task,
semantic->func_test->script->number->value );
str_append( &name, string->value );
}
else {
str_append_number( &name,
semantic->func_test->script->number->value );
}
break;
}
magic_id->string = t_intern_string_copy( semantic->task,
name.value, name.length );
Expand Down
9 changes: 6 additions & 3 deletions src/task.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,8 @@ struct node {
NODE_MEMCPY,
NODE_CONVERSION,
NODE_SURE,
NODE_FUNCNAME,
NODE_SCRIPTID,
NODE_DO,
NODE_COMPOUNDLITERAL,
// 60
NODE_MAGICID,
} type;
};
Expand Down Expand Up @@ -312,12 +309,18 @@ struct compound_literal {
struct var* var;
};

// List of magic identifiers:
// __NAMESPACE__ | Fully-qualified name of the current namespace.
// __FUNCTION__ | Name of the current function.
// __SCRIPT__ | Name or number of the current script.
struct magic_id {
struct node node;
struct pos pos;
struct indexed_string* string;
enum {
MAGICID_NAMESPACE,
MAGICID_FUNCTION,
MAGICID_SCRIPT,
} name;
};

Expand Down

0 comments on commit 4da7e63

Please sign in to comment.