Skip to content

Commit

Permalink
p2 namespaces (not yet)
Browse files Browse the repository at this point in the history
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
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 6 deletions.
2 changes: 1 addition & 1 deletion Makefile
Expand Up @@ -22,7 +22,7 @@ endif
SRC_SYN = syn/syntax.c
SRC_P2_SYN = syn/syntax-p5.c
SRC_POTION = front/potion.c
SRC_P2 = front/p2.c
SRC_P2 = core/p2.c front/p2.c

FPIC =
OPIC = o
Expand Down
109 changes: 109 additions & 0 deletions core/p2.c
@@ -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);
}
}


20 changes: 20 additions & 0 deletions core/p2.h
Expand Up @@ -24,6 +24,26 @@

extern PN PN_use;

#include "table.h"

/// a namespace is a hash of dynamic symbolnames
///
struct PNNamespace {
PN_OBJECT_HEADER; ///< PNType vt; PNUniq uniq
PN_TABLE_HEADER; ///< PN_SIZE n_buckets, size, n_occupied, upper_bound
char table[0];
};

#define PN_TNAMESPACE PN_TUSER+1
PN potion_nstuple_set(Potion *P, PN name);
PN potion_nstuple_push(Potion *P, PN name);
PN potion_nstuple_pop(Potion *P);
PN potion_pkg(Potion *P, PN cl, PN self);
PN potion_pkg_create(Potion *P, PN pkg);
PN potion_pkg_put(Potion *P, PN name, PN value);
PN potion_pkg_at(Potion *P, PN cl, PN self, PN key);
PN potion_sym_at(Potion *P, PN name); //not yet

#endif

//
Expand Down
6 changes: 5 additions & 1 deletion core/potion.h
Expand Up @@ -582,7 +582,7 @@ struct Potion_State {
PN_OBJECT_HEADER; ///< PNType vt; PNUniq uniq
PNTarget target; ///< the jit
struct PNTable *strings; ///< table of all strings
PN lobby; ///< root namespace
PN lobby; ///< root class
PNFlex * volatile vts; ///< built in types
PN source, input; ///< parser input and output
int yypos; ///< parser buffer position
Expand All @@ -591,6 +591,9 @@ struct Potion_State {
PN call, callset; ///< generic call and callset
int prec; ///< decimal precision
struct PNMemory *mem; ///< allocator/gc
#ifdef P2
struct PNTuple *nstuple; ///< stack of namespace hashes
#endif
Potion_Flags flags; ///< vm flags: execution model and debug flags
};

Expand Down Expand Up @@ -784,6 +787,7 @@ PN potion_tuple_push(Potion *, PN, PN);
PN_SIZE potion_tuple_push_unless(Potion *, PN, PN);
PN_SIZE potion_tuple_find(Potion *, PN, PN);
PN potion_tuple_at(Potion *, PN, PN, PN);
PN potion_tuple_last(Potion *, PN, PN);
PN potion_table_empty(Potion *);
PN potion_table_put(Potion *, PN, PN, PN, PN);
PN potion_table_set(Potion *, PN, PN, PN);
Expand Down
14 changes: 10 additions & 4 deletions syn/syntax-p5.y
Expand Up @@ -95,15 +95,15 @@ statements =
(sep? s2:stmt { $$ = s1 = PN_PUSH(s1, s2) })* sep?
| '' { $$ = PN_NIL }

stmt = PACKAGE arg-name semi {} # TODO: set namespace
stmt = package
| subrout
| use
| ifstmt
| assigndecl
| s:sets semi
( or x:sets semi { s = PN_OP(AST_OR, s, x) }
| and x:sets semi { s = PN_OP(AST_AND, s, x) })*
{ $$ = s }
#( or x:sets semi { s = PN_OP(AST_OR, s, x) }
#| and x:sets semi { s = PN_OP(AST_AND, s, x) })*
{ $$ = s }
| expr

SUB = "sub" space+
Expand All @@ -114,6 +114,12 @@ ELSIF = "elsif" space+
ELSE = "else" space+
MY = "my" space+

# call them in the compiler
package = PACKAGE n:id - '{' - b:block - '}'
{ $$ = PN_PUSH(PN_PUSH(PN_AST(EXPR, PN_AST2(MSG, n, PN_STR("nstuple_push"))),
PN_AST(BLOCK, b)),
PN_AST(EXPR, PN_AST(MSG, PN_STR("nstuple_pop")))) }
| PACKAGE n:id - semi { potion_nstuple_set(P, n) }
subrout = SUB n:id - ( '(' p:sig_p5 ')' )? - b:block -
{ $$ = PN_AST2(ASSIGN, PN_AST(EXPR, PN_AST(MSG, n)), PN_AST2(PROTO, p, b)) }
# so far no difference in global or lex assignment
Expand Down

0 comments on commit 0a7cf06

Please sign in to comment.