Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
nstuple is a stack of scoped packages to support nested packages, like package NAME { package SUBPKG; } a namespace is a perl5 like hash of symbol names and other namespace subhashes with :: suffix. The root namespace and first nstuple is the main:: namespace hash.
- Loading branch information
Reini Urban
committed
May 15, 2013
1 parent
3828fb5
commit 0a7cf06
Showing
5 changed files
with
145 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
/**\file p2.c | ||
perl specific functions. global namespaces, ... | ||
%main:: = { | ||
hash of symbols, ... | ||
+ hash of subpackages:: | ||
} | ||
P->lobby->nstuple: stack of nested package blocks, beginning with main:: | ||
the last is always the current package. | ||
(c) 2013 by perl11 org | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include "p2.h" | ||
#include "internal.h" | ||
#include "table.h" | ||
#include "ast.h" | ||
|
||
#define CUR_PKG potion_tuple_last(P, 0, (PN)P->nstuple) | ||
|
||
void potion_p2_init(Potion *P) { | ||
PN ns_vt = potion_type_new2(P, PN_TNAMESPACE, PN_VTABLE(PN_TTABLE), potion_str(P, "Namespace")); | ||
potion_method(P->lobby, "package", potion_pkg, 0); | ||
// derive all namespace methods from PNTable | ||
//potion_method(ns_vt, "push", potion_pkg_push, "name=S"); | ||
//potion_method(ns_vt, "pop", potion_pkg_pop, 0); | ||
potion_method(ns_vt, "create", potion_ns_create, "name=S"); | ||
//potion_method(ns_vt, "put", potion_pkg_put, "name=S"); | ||
//potion_type_call_is(ns_vt, PN_FUNC(potion_pkg), "name=S"); | ||
potion_tuple_push(P, (PN)P->nstuple, PN_STR("main")); | ||
} | ||
|
||
/** PNNamespace i.e. a Hash of names | ||
we maintain a stack of current namespaces for scoped package NAME {} blocks, with | ||
main:: always the first, and the current always the last. | ||
\return current namespace, i.e. package hash */ | ||
PN potion_pkg(Potion *P, PN cl, PN self) { | ||
return CUR_PKG; | ||
} | ||
/** | ||
set a new namespace, overriding old, but not the first - main::. | ||
\param PNString name | ||
Needed for package NAME; */ | ||
PN potion_nstuple_set(Potion *P, PN name) { | ||
PN t = (PN)P->nstuple; | ||
PN ns = potion_table_empty(P); | ||
PN_SIZE len = PN_TUPLE_LEN(t); | ||
// prev ns | ||
if (len == 1) { | ||
return potion_tuple_push(P, t, ns); | ||
} else { | ||
return potion_tuple_put(P, 0, t, len-1, ns); | ||
} | ||
} | ||
/** | ||
"push" a new namespace to the namespace stack. | ||
Initialized with "main" | ||
\param PNString name | ||
Needed at the beginning of scoped package NAME {} blocks. */ | ||
PN potion_nstuple_push(Potion *P, PN name) { | ||
return potion_tuple_push(P, P->nstuple, name + "::"); | ||
} | ||
/** | ||
"pop" the last namespace from the namespace stack and return it. | ||
Needed at the end of scoped package NAME {} blocks. */ | ||
PN potion_nstuple_pop(Potion *P) { | ||
return potion_tuple_pop(P, 0, P->nstuple); | ||
} | ||
|
||
/** create a new subpackage under the current package | ||
\param PNString pkg */ | ||
PN potion_pkg_create(Potion *P, PN pkg) { | ||
return potion_table_set(P, 0, CUR_PKG, | ||
potion_strcat(P, PN_STR_PTR(pkg),"::")); | ||
} | ||
/** | ||
put/intern a new symbol and value into the current namespace | ||
\param PNString name */ | ||
PN potion_pkg_put(Potion *P, PN name, PN value) { | ||
return potion_table_put(P, 0, CUR_PKG, name, value); | ||
} | ||
/** | ||
"find" a symbol in the namespace, return its value. | ||
\param PNString name */ | ||
PN potion_pkg_at(Potion *P, PN cl, PN self, PN key) { | ||
return potion_table_at(P, cl, CUR_PKG, key); | ||
} | ||
/** | ||
\param PNString name | ||
\returns upper the namespace from name. | ||
i.e. My::Class => My, My => main */ | ||
PN potion_pkg_upper(Potion *P, PN cl, PN name) { | ||
char *p = PN_STR_PTR(name); | ||
return potion_table_at(P, cl, CUR_PKG, name); | ||
} | ||
/** "find" a symbol by traversing the namespace parts+hashes, return its value. | ||
\param PNString name */ | ||
PN potion_sym_at(Potion *P, PN name) { | ||
char *p = PN_STR_PTR(name); | ||
char *c; | ||
// see gv.c: walk the spliced :: parts and lookup the ns in the hash in parallel | ||
while (c = strchr(p, "::")) { | ||
PN ns = PN_NIL; | ||
return potion_table_at(P, 0, ns, name); | ||
} | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters