mirror of
https://github.com/ganelson/inform.git
synced 2024-06-29 05:24:57 +03:00
Slightly clarified namespaces
This commit is contained in:
parent
1f81d09a58
commit
baa615c76f
|
@ -7,6 +7,8 @@ Include (-
|
|||
[ greet;
|
||||
summon();
|
||||
print "greet in Alpha^";
|
||||
ponder();
|
||||
main`ponder();
|
||||
dismiss();
|
||||
Beta`dismiss();
|
||||
];
|
||||
|
@ -15,21 +17,30 @@ Include (-
|
|||
print "dismiss in Alpha, where EXAMPLE = ", EXAMPLE, "^";
|
||||
];
|
||||
|
||||
[ ponder;
|
||||
print "ponder in Alpha^";
|
||||
];
|
||||
|
||||
+namespace(Beta);
|
||||
|
||||
[ dismiss;
|
||||
print "dismiss in Beta^";
|
||||
];
|
||||
|
||||
+namespace();
|
||||
+namespace(main);
|
||||
|
||||
Constant EXAMPLE = 10;
|
||||
|
||||
[ summon;
|
||||
print "summon outside of namespace where Alpha`EXAMPLE = ", Alpha`EXAMPLE, "^";
|
||||
print "summon in main where Alpha`EXAMPLE = ", Alpha`EXAMPLE, "^";
|
||||
];
|
||||
|
||||
[ dismiss;
|
||||
print "dismiss outside of namespace^";
|
||||
print "dismiss in main^";
|
||||
];
|
||||
|
||||
[ ponder;
|
||||
print "ponder in main^";
|
||||
];
|
||||
|
||||
-).
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
summon outside of namespace where Alpha`EXAMPLE = 20
|
||||
summon in main where Alpha`EXAMPLE = 20
|
||||
greet in Alpha
|
||||
ponder in Alpha
|
||||
ponder in main
|
||||
dismiss in Alpha, where EXAMPLE = 20
|
||||
dismiss in Beta
|
||||
Here are the dismiss functions:
|
||||
dismiss in Alpha, where EXAMPLE = 20
|
||||
dismiss in Beta
|
||||
dismiss outside of namespace
|
||||
dismiss in main
|
||||
The value of EXAMPLE here is 10
|
||||
|
|
|
@ -534,3 +534,17 @@ inter_name *HierarchyLocations::find_by_name(inter_tree *I, text_stream *name) {
|
|||
}
|
||||
return try;
|
||||
}
|
||||
|
||||
inter_name *HierarchyLocations::find_by_implied_name(inter_tree *I, text_stream *name,
|
||||
text_stream *from_namespace) {
|
||||
if (Str::len(name) == 0) internal_error("empty extern");
|
||||
inter_name *try = HierarchyLocations::name_to_iname(I, name);
|
||||
if (try == NULL) {
|
||||
TEMPORARY_TEXT(N)
|
||||
WRITE_TO(N, "implied`%S`%S", from_namespace, name);
|
||||
HierarchyLocations::con(I, -1, N, LocationRequirements::plug());
|
||||
try = HierarchyLocations::name_to_iname(I, N);
|
||||
DISCARD_TEXT(N)
|
||||
}
|
||||
return try;
|
||||
}
|
||||
|
|
|
@ -84,8 +84,9 @@ So the above internal error cannot occur.
|
|||
@<Interpret this as an identifier@> =
|
||||
text_stream *seek = name;
|
||||
TEMPORARY_TEXT(N)
|
||||
int add_namespace = FALSE;
|
||||
if (Str::len(finder.from_namespace) > 0) {
|
||||
int add_namespace = TRUE;
|
||||
add_namespace = TRUE;
|
||||
for (int i=0; i<Str::len(name); i++)
|
||||
if (Str::get_at(name, i) == '`')
|
||||
add_namespace = FALSE;
|
||||
|
@ -105,7 +106,10 @@ So the above internal error cannot occur.
|
|||
if (S) goto Exit;
|
||||
S = InterSymbolsTable::symbol_from_name(LargeScale::main_scope(I), name);
|
||||
if (S) goto Exit;
|
||||
S = InterNames::to_symbol(HierarchyLocations::find_by_name(I, seek));
|
||||
if (add_namespace)
|
||||
S = InterNames::to_symbol(HierarchyLocations::find_by_implied_name(I, name, finder.from_namespace));
|
||||
else
|
||||
S = InterNames::to_symbol(HierarchyLocations::find_by_name(I, seek));
|
||||
Exit: ;
|
||||
DISCARD_TEXT(N)
|
||||
return S;
|
||||
|
|
|
@ -418,15 +418,24 @@ void Wiring::connect_plugs_to_sockets(inter_tree *I) {
|
|||
last_tick = i;
|
||||
}
|
||||
if (last_tick >= 0) {
|
||||
TEMPORARY_TEXT(N)
|
||||
for (int i=last_tick+1; i<Str::len(name); i++)
|
||||
PUT_TO(N, Str::get_at(name, i));
|
||||
socket = Wiring::find_socket(I, N);
|
||||
if (socket) {
|
||||
LOGIF(INTER_CONNECTORS, "Wiring plug to socket with global name: $3\n", S);
|
||||
Wiring::wire_plug(S, socket);
|
||||
if ((Str::prefix_eq(name, I"implied`", 8)) ||
|
||||
(Str::prefix_eq(name, I"main`", 5))) {
|
||||
TEMPORARY_TEXT(N)
|
||||
TEMPORARY_TEXT(NS)
|
||||
for (int i=8; i<last_tick; i++)
|
||||
PUT_TO(NS, Str::get_at(name, i));
|
||||
if (Str::eq(NS, I"main")) Str::clear(NS);
|
||||
for (int i=last_tick+1; i<Str::len(name); i++)
|
||||
PUT_TO(N, Str::get_at(name, i));
|
||||
socket = Wiring::find_socket(I, N);
|
||||
if (socket) {
|
||||
LOGIF(INTER_CONNECTORS, "Wire implied plug '%S' to socket with global name: $3\n",
|
||||
name, S);
|
||||
Wiring::wire_plug(S, socket);
|
||||
}
|
||||
DISCARD_TEXT(N)
|
||||
DISCARD_TEXT(NS)
|
||||
}
|
||||
DISCARD_TEXT(N)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -778,19 +778,36 @@ These have package types |_function| and |_code| respectively.
|
|||
|
||||
=
|
||||
void CompileSplatsStage::apply_annotations(text_stream *A, text_stream *NS, inter_symbol *S) {
|
||||
if (Str::len(NS) > 0) {
|
||||
LOGIF(INTER_CONNECTORS, "Assign namespace '%S' to $3\n", NS, S);
|
||||
InterSymbol::set_namespace(S, NS);
|
||||
int apply_private = NOT_APPLICABLE, L = Str::len(NS);
|
||||
if (Str::get_last_char(NS) == '+') apply_private = FALSE;
|
||||
if (Str::get_last_char(NS) == '-') apply_private = TRUE;
|
||||
if (apply_private != NOT_APPLICABLE) L--;
|
||||
if (L > 0) {
|
||||
TEMPORARY_TEXT(N)
|
||||
for (int i=0; i<L; i++) PUT_TO(N, Str::get_at(NS, i));
|
||||
LOGIF(INTER_CONNECTORS, "Assign namespace '%S' to $3\n", N, S);
|
||||
InterSymbol::set_namespace(S, N);
|
||||
DISCARD_TEXT(N)
|
||||
}
|
||||
if (Str::len(A) > 0) {
|
||||
LOGIF(INTER_CONNECTORS, "Trying to apply '%S' to $3\n", A, S);
|
||||
for (I6_annotation *IA = I6Annotations::parse(A); IA; IA = IA->next) {
|
||||
if (Str::eq_insensitive(IA->identifier, I"private")) {
|
||||
if ((IA->terms == NULL) || (LinkedLists::len(IA->terms) == 0)) {
|
||||
SymbolAnnotation::set_b(S, PRIVATE_IANN, TRUE);
|
||||
if (apply_private == TRUE)
|
||||
PipelineErrors::kit_error("the +private annotation is redundant here", NULL);
|
||||
apply_private = TRUE;
|
||||
} else {
|
||||
PipelineErrors::kit_error("the +private annotation does not take any terms", NULL);
|
||||
}
|
||||
} else if (Str::eq_insensitive(IA->identifier, I"public")) {
|
||||
if ((IA->terms == NULL) || (LinkedLists::len(IA->terms) == 0)) {
|
||||
if (apply_private == FALSE)
|
||||
PipelineErrors::kit_error("the +public annotation is redundant here", NULL);
|
||||
apply_private = FALSE;
|
||||
} else {
|
||||
PipelineErrors::kit_error("the +public annotation does not take any terms", NULL);
|
||||
}
|
||||
} else if (Str::eq_insensitive(IA->identifier, I"replacing")) {
|
||||
text_stream *from = I"_";
|
||||
if (IA->terms) {
|
||||
|
@ -809,6 +826,7 @@ void CompileSplatsStage::apply_annotations(text_stream *A, text_stream *NS, inte
|
|||
}
|
||||
}
|
||||
}
|
||||
if (apply_private == TRUE) SymbolAnnotation::set_b(S, PRIVATE_IANN, TRUE);
|
||||
}
|
||||
|
||||
@h Plumbing.
|
||||
|
|
|
@ -301,14 +301,40 @@ void ParsingStages::splat(text_stream *R, simple_tangle_docket *docket) {
|
|||
if ((IA) && (Str::eq_insensitive(IA->identifier, I"namespace"))) {
|
||||
rpi_docket_state *state = (rpi_docket_state *) docket->state;
|
||||
Str::clear(state->namespace);
|
||||
int private = NOT_APPLICABLE;
|
||||
I6_annotation_term *term;
|
||||
LOOP_OVER_LINKED_LIST(term, I6_annotation_term, IA->terms)
|
||||
LOOP_OVER_LINKED_LIST(term, I6_annotation_term, IA->terms) {
|
||||
if (Str::eq_insensitive(term->key, I"_")) {
|
||||
WRITE_TO(state->namespace, "%S", term->value);
|
||||
} else if (Str::eq_insensitive(term->key, I"access")) {
|
||||
if (Str::eq_insensitive(term->value, I"private")) private = TRUE;
|
||||
else if (Str::eq_insensitive(term->value, I"public")) private = FALSE;
|
||||
else PipelineErrors::kit_error(
|
||||
"the 'access' must be 'private' or 'public', not '%S'", term->value);
|
||||
} else {
|
||||
PipelineErrors::kit_error(
|
||||
"the +replacing annotation does not take the term '%S'", term->key);
|
||||
"the +namespace annotation does not take the term '%S'", term->key);
|
||||
}
|
||||
}
|
||||
int bad_name = FALSE;
|
||||
for (int i=0; i<Str::len(state->namespace); i++) {
|
||||
wchar_t c = Str::get_at(state->namespace, i);
|
||||
if (i == 0) {
|
||||
if (Characters::isalpha(c) == FALSE) bad_name = TRUE;
|
||||
} else {
|
||||
if ((Characters::isalnum(c) == FALSE) && (c != '_')) bad_name = TRUE;
|
||||
}
|
||||
}
|
||||
if (bad_name)
|
||||
PipelineErrors::kit_error(
|
||||
"a namespace name should begin with a letter and contain "
|
||||
"only alphanumeric characters or '_'", NULL);
|
||||
if (Str::len(state->namespace) == 0)
|
||||
PipelineErrors::kit_error(
|
||||
"use '+namespace(main);' to return to the global namespace", NULL);
|
||||
if (Str::eq(state->namespace, I"main")) Str::clear(state->namespace);
|
||||
if (private == TRUE) PUT_TO(state->namespace, '-');
|
||||
if (private == FALSE) PUT_TO(state->namespace, '+');
|
||||
} else {
|
||||
(*(docket->error_callback))(
|
||||
"this annotation seems not to apply to any directive: '%S'", A);
|
||||
|
|
Loading…
Reference in a new issue