mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
...
This commit is contained in:
parent
f9de245bc6
commit
fa5df75248
@ -1,20 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "pocketpy/common/vector.h"
|
#include "pocketpy/common/vector.h"
|
||||||
#include "pocketpy/common/utils.h"
|
#include "pocketpy/common/utils.h"
|
||||||
|
#include "pocketpy/pocketpy.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* string_view */
|
|
||||||
typedef struct c11_sv{
|
|
||||||
const char* data;
|
|
||||||
int size;
|
|
||||||
} c11_sv;
|
|
||||||
|
|
||||||
/* string */
|
/* string */
|
||||||
typedef struct c11_string{
|
typedef struct c11_string{
|
||||||
// int size | char[] | '\0'
|
// int size | char[] | '\0'
|
||||||
|
@ -7,9 +7,6 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint16_t py_name2(c11_sv name);
|
|
||||||
c11_sv py_name2sv(uint16_t index);
|
|
||||||
|
|
||||||
void py_Name__initialize();
|
void py_Name__initialize();
|
||||||
void py_Name__finalize();
|
void py_Name__finalize();
|
||||||
|
|
||||||
|
@ -124,14 +124,14 @@ void FuncDecl__add_arg(FuncDecl* self, py_Name name);
|
|||||||
void FuncDecl__add_kwarg(FuncDecl* self, py_Name name, const py_TValue* value);
|
void FuncDecl__add_kwarg(FuncDecl* self, py_Name name, const py_TValue* value);
|
||||||
void FuncDecl__add_starred_arg(FuncDecl* self, py_Name name);
|
void FuncDecl__add_starred_arg(FuncDecl* self, py_Name name);
|
||||||
void FuncDecl__add_starred_kwarg(FuncDecl* self, py_Name name);
|
void FuncDecl__add_starred_kwarg(FuncDecl* self, py_Name name);
|
||||||
FuncDecl_ FuncDecl__build(const char* name,
|
FuncDecl_ FuncDecl__build(c11_sv name,
|
||||||
const char** args,
|
c11_sv* args,
|
||||||
int argc,
|
int argc,
|
||||||
const char* starred_arg,
|
c11_sv starred_arg,
|
||||||
const char** kwargs,
|
c11_sv* kwargs,
|
||||||
int kwargc,
|
int kwargc,
|
||||||
py_Ref kwdefaults, // a tuple contains default values
|
py_Ref kwdefaults, // a tuple contains default values
|
||||||
const char* starred_kwarg,
|
c11_sv starred_kwarg,
|
||||||
const char* docstring);
|
const char* docstring);
|
||||||
|
|
||||||
// runtime function
|
// runtime function
|
||||||
|
@ -15,6 +15,12 @@ typedef int16_t py_Type;
|
|||||||
typedef int64_t py_i64;
|
typedef int64_t py_i64;
|
||||||
typedef double py_f64;
|
typedef double py_f64;
|
||||||
|
|
||||||
|
/* string_view */
|
||||||
|
typedef struct c11_sv{
|
||||||
|
const char* data;
|
||||||
|
int size;
|
||||||
|
} c11_sv;
|
||||||
|
|
||||||
/// Generic reference.
|
/// Generic reference.
|
||||||
typedef py_TValue* py_Ref;
|
typedef py_TValue* py_Ref;
|
||||||
/// An object reference which has the same lifespan as the object.
|
/// An object reference which has the same lifespan as the object.
|
||||||
@ -57,7 +63,6 @@ void py_newfloat(py_Ref, py_f64);
|
|||||||
void py_newbool(py_Ref, bool);
|
void py_newbool(py_Ref, bool);
|
||||||
void py_newstr(py_Ref, const char*);
|
void py_newstr(py_Ref, const char*);
|
||||||
void py_newstrn(py_Ref, const char*, int);
|
void py_newstrn(py_Ref, const char*, int);
|
||||||
// void py_newfstr(py_Ref, const char*, ...);
|
|
||||||
unsigned char* py_newbytes(py_Ref, int);
|
unsigned char* py_newbytes(py_Ref, int);
|
||||||
void py_newnone(py_Ref);
|
void py_newnone(py_Ref);
|
||||||
void py_newnotimplemented(py_Ref out);
|
void py_newnotimplemented(py_Ref out);
|
||||||
@ -75,6 +80,9 @@ void py_newlistn(py_Ref, int n);
|
|||||||
|
|
||||||
py_Name py_name(const char*);
|
py_Name py_name(const char*);
|
||||||
const char* py_name2str(py_Name);
|
const char* py_name2str(py_Name);
|
||||||
|
py_Name py_namev(c11_sv name);
|
||||||
|
c11_sv py_name2sv(py_Name);
|
||||||
|
|
||||||
bool py_ismagicname(py_Name);
|
bool py_ismagicname(py_Name);
|
||||||
|
|
||||||
// opaque types
|
// opaque types
|
||||||
@ -98,6 +106,7 @@ bool py_tobool(const py_Ref);
|
|||||||
py_Type py_totype(const py_Ref);
|
py_Type py_totype(const py_Ref);
|
||||||
const char* py_tostr(const py_Ref);
|
const char* py_tostr(const py_Ref);
|
||||||
const char* py_tostrn(const py_Ref, int* size);
|
const char* py_tostrn(const py_Ref, int* size);
|
||||||
|
c11_sv py_tosv(const py_Ref);
|
||||||
unsigned char* py_tobytes(const py_Ref, int* size);
|
unsigned char* py_tobytes(const py_Ref, int* size);
|
||||||
|
|
||||||
void* py_touserdata(const py_Ref);
|
void* py_touserdata(const py_Ref);
|
||||||
@ -135,14 +144,14 @@ py_ObjectRef py_bind2(py_Ref obj,
|
|||||||
|
|
||||||
py_ObjectRef py_bind3(py_Ref obj,
|
py_ObjectRef py_bind3(py_Ref obj,
|
||||||
py_CFunction f,
|
py_CFunction f,
|
||||||
const char* name,
|
c11_sv name,
|
||||||
const char** args,
|
c11_sv* args,
|
||||||
int argc,
|
int argc,
|
||||||
const char* starred_arg,
|
c11_sv starred_arg,
|
||||||
const char** kwargs,
|
c11_sv* kwargs,
|
||||||
int kwargc,
|
int kwargc,
|
||||||
py_Ref kwdefaults, // a tuple contains default values
|
py_Ref kwdefaults, // a tuple contains default values
|
||||||
const char* starred_kwarg,
|
c11_sv starred_kwarg,
|
||||||
enum BindType bt,
|
enum BindType bt,
|
||||||
const char* docstring,
|
const char* docstring,
|
||||||
int slots);
|
int slots);
|
||||||
|
@ -31,9 +31,9 @@ void py_Name__finalize() {
|
|||||||
c11_vector__dtor(&_r_interned);
|
c11_vector__dtor(&_r_interned);
|
||||||
}
|
}
|
||||||
|
|
||||||
py_Name py_name(const char* name) { return py_name2((c11_sv){name, strlen(name)}); }
|
py_Name py_name(const char* name) { return py_namev((c11_sv){name, strlen(name)}); }
|
||||||
|
|
||||||
py_Name py_name2(c11_sv name) {
|
py_Name py_namev(c11_sv name) {
|
||||||
// TODO: PK_GLOBAL_SCOPE_LOCK()
|
// TODO: PK_GLOBAL_SCOPE_LOCK()
|
||||||
uint16_t index = c11_smallmap_s2n__get(&_interned, name, 0);
|
uint16_t index = c11_smallmap_s2n__get(&_interned, name, 0);
|
||||||
if(index != 0) return index;
|
if(index != 0) return index;
|
||||||
|
@ -635,7 +635,7 @@ static void _load_simple_expr(Ctx* ctx, c11_sv expr, int line) {
|
|||||||
// name or name.name
|
// name or name.name
|
||||||
bool is_fastpath = false;
|
bool is_fastpath = false;
|
||||||
if(is_identifier(expr)) {
|
if(is_identifier(expr)) {
|
||||||
Ctx__emit_(ctx, OP_LOAD_NAME, py_name2(expr), line);
|
Ctx__emit_(ctx, OP_LOAD_NAME, py_namev(expr), line);
|
||||||
is_fastpath = true;
|
is_fastpath = true;
|
||||||
} else {
|
} else {
|
||||||
int dot = c11_sv__index(expr, '.');
|
int dot = c11_sv__index(expr, '.');
|
||||||
@ -643,8 +643,8 @@ static void _load_simple_expr(Ctx* ctx, c11_sv expr, int line) {
|
|||||||
c11_sv a = {expr.data, dot}; // expr[:dot]
|
c11_sv a = {expr.data, dot}; // expr[:dot]
|
||||||
c11_sv b = {expr.data + (dot + 1), expr.size - (dot + 1)}; // expr[dot+1:]
|
c11_sv b = {expr.data + (dot + 1), expr.size - (dot + 1)}; // expr[dot+1:]
|
||||||
if(is_identifier(a) && is_identifier(b)) {
|
if(is_identifier(a) && is_identifier(b)) {
|
||||||
Ctx__emit_(ctx, OP_LOAD_NAME, py_name2(a), line);
|
Ctx__emit_(ctx, OP_LOAD_NAME, py_namev(a), line);
|
||||||
Ctx__emit_(ctx, OP_LOAD_ATTR, py_name2(b), line);
|
Ctx__emit_(ctx, OP_LOAD_ATTR, py_namev(b), line);
|
||||||
is_fastpath = true;
|
is_fastpath = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1539,7 +1539,7 @@ static Error* EXPR_VARS(Compiler* self) {
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
do {
|
do {
|
||||||
consume(TK_ID);
|
consume(TK_ID);
|
||||||
py_Name name = py_name2(Token__sv(prev()));
|
py_Name name = py_namev(Token__sv(prev()));
|
||||||
NameExpr* e = NameExpr__new(prev()->line, name, name_scope(self));
|
NameExpr* e = NameExpr__new(prev()->line, name, name_scope(self));
|
||||||
Ctx__s_push(ctx(), (Expr*)e);
|
Ctx__s_push(ctx(), (Expr*)e);
|
||||||
count += 1;
|
count += 1;
|
||||||
@ -1785,7 +1785,7 @@ static Error* exprGroup(Compiler* self) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Error* exprName(Compiler* self) {
|
static Error* exprName(Compiler* self) {
|
||||||
py_Name name = py_name2(Token__sv(prev()));
|
py_Name name = py_namev(Token__sv(prev()));
|
||||||
NameScope scope = name_scope(self);
|
NameScope scope = name_scope(self);
|
||||||
// promote this name to global scope if needed
|
// promote this name to global scope if needed
|
||||||
if(c11_smallmap_n2i__contains(&ctx()->global_names, name)) { scope = NAME_GLOBAL; }
|
if(c11_smallmap_n2i__contains(&ctx()->global_names, name)) { scope = NAME_GLOBAL; }
|
||||||
@ -1796,7 +1796,7 @@ static Error* exprName(Compiler* self) {
|
|||||||
|
|
||||||
static Error* exprAttrib(Compiler* self) {
|
static Error* exprAttrib(Compiler* self) {
|
||||||
consume(TK_ID);
|
consume(TK_ID);
|
||||||
py_Name name = py_name2(Token__sv(prev()));
|
py_Name name = py_namev(Token__sv(prev()));
|
||||||
AttribExpr* e = AttribExpr__new(prev()->line, Ctx__s_popx(ctx()), name);
|
AttribExpr* e = AttribExpr__new(prev()->line, Ctx__s_popx(ctx()), name);
|
||||||
Ctx__s_push(ctx(), (Expr*)e);
|
Ctx__s_push(ctx(), (Expr*)e);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1909,7 +1909,7 @@ static Error* exprCall(Compiler* self) {
|
|||||||
if(curr()->type == TK_RPAREN) break;
|
if(curr()->type == TK_RPAREN) break;
|
||||||
if(curr()->type == TK_ID && next()->type == TK_ASSIGN) {
|
if(curr()->type == TK_ID && next()->type == TK_ASSIGN) {
|
||||||
consume(TK_ID);
|
consume(TK_ID);
|
||||||
py_Name key = py_name2(Token__sv(prev()));
|
py_Name key = py_namev(Token__sv(prev()));
|
||||||
consume(TK_ASSIGN);
|
consume(TK_ASSIGN);
|
||||||
check(EXPR(self));
|
check(EXPR(self));
|
||||||
CallExprKwArg kw = {key, Ctx__s_popx(ctx())};
|
CallExprKwArg kw = {key, Ctx__s_popx(ctx())};
|
||||||
@ -2235,7 +2235,7 @@ static Error* _compile_f_args(Compiler* self, FuncDecl* decl, bool enable_type_h
|
|||||||
state = 3;
|
state = 3;
|
||||||
}
|
}
|
||||||
consume(TK_ID);
|
consume(TK_ID);
|
||||||
py_Name name = py_name2(Token__sv(prev()));
|
py_Name name = py_namev(Token__sv(prev()));
|
||||||
|
|
||||||
// check duplicate argument name
|
// check duplicate argument name
|
||||||
if(FuncDecl__is_duplicated_arg(decl, name)) {
|
if(FuncDecl__is_duplicated_arg(decl, name)) {
|
||||||
@ -2301,9 +2301,9 @@ static Error* compile_function(Compiler* self, int decorators) {
|
|||||||
Ctx__s_emit_decorators(ctx(), decorators);
|
Ctx__s_emit_decorators(ctx(), decorators);
|
||||||
|
|
||||||
if(ctx()->is_compiling_class) {
|
if(ctx()->is_compiling_class) {
|
||||||
Ctx__emit_(ctx(), OP_STORE_CLASS_ATTR, py_name2(decl_name), prev()->line);
|
Ctx__emit_(ctx(), OP_STORE_CLASS_ATTR, py_namev(decl_name), prev()->line);
|
||||||
} else {
|
} else {
|
||||||
NameExpr* e = NameExpr__new(prev()->line, py_name2(decl_name), name_scope(self));
|
NameExpr* e = NameExpr__new(prev()->line, py_namev(decl_name), name_scope(self));
|
||||||
vtemit_store((Expr*)e, ctx());
|
vtemit_store((Expr*)e, ctx());
|
||||||
vtdelete((Expr*)e);
|
vtdelete((Expr*)e);
|
||||||
}
|
}
|
||||||
@ -2340,7 +2340,7 @@ static Error* compile_normal_import(Compiler* self) {
|
|||||||
consume(TK_ID);
|
consume(TK_ID);
|
||||||
name = Token__sv(prev());
|
name = Token__sv(prev());
|
||||||
}
|
}
|
||||||
Ctx__emit_store_name(ctx(), name_scope(self), py_name2(name), prev()->line);
|
Ctx__emit_store_name(ctx(), name_scope(self), py_namev(name), prev()->line);
|
||||||
} while(match(TK_COMMA));
|
} while(match(TK_COMMA));
|
||||||
consume_end_stmt();
|
consume_end_stmt();
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -2411,12 +2411,12 @@ __EAT_DOTS_END:
|
|||||||
Ctx__emit_(ctx(), OP_DUP_TOP, BC_NOARG, BC_KEEPLINE);
|
Ctx__emit_(ctx(), OP_DUP_TOP, BC_NOARG, BC_KEEPLINE);
|
||||||
consume(TK_ID);
|
consume(TK_ID);
|
||||||
c11_sv name = Token__sv(prev());
|
c11_sv name = Token__sv(prev());
|
||||||
Ctx__emit_(ctx(), OP_LOAD_ATTR, py_name2(name), prev()->line);
|
Ctx__emit_(ctx(), OP_LOAD_ATTR, py_namev(name), prev()->line);
|
||||||
if(match(TK_AS)) {
|
if(match(TK_AS)) {
|
||||||
consume(TK_ID);
|
consume(TK_ID);
|
||||||
name = Token__sv(prev());
|
name = Token__sv(prev());
|
||||||
}
|
}
|
||||||
Ctx__emit_store_name(ctx(), name_scope(self), py_name2(name), prev()->line);
|
Ctx__emit_store_name(ctx(), name_scope(self), py_namev(name), prev()->line);
|
||||||
} while(match(TK_COMMA));
|
} while(match(TK_COMMA));
|
||||||
Ctx__emit_(ctx(), OP_POP_TOP, BC_NOARG, BC_KEEPLINE);
|
Ctx__emit_(ctx(), OP_POP_TOP, BC_NOARG, BC_KEEPLINE);
|
||||||
consume_end_stmt();
|
consume_end_stmt();
|
||||||
@ -2515,7 +2515,7 @@ static Error* compile_stmt(Compiler* self) {
|
|||||||
case TK_GLOBAL:
|
case TK_GLOBAL:
|
||||||
do {
|
do {
|
||||||
consume(TK_ID);
|
consume(TK_ID);
|
||||||
py_Name name = py_name2(Token__sv(prev()));
|
py_Name name = py_namev(Token__sv(prev()));
|
||||||
c11_smallmap_n2i__set(&ctx()->global_names, name, 0);
|
c11_smallmap_n2i__set(&ctx()->global_names, name, 0);
|
||||||
} while(match(TK_COMMA));
|
} while(match(TK_COMMA));
|
||||||
consume_end_stmt();
|
consume_end_stmt();
|
||||||
@ -2560,7 +2560,7 @@ static Error* compile_stmt(Compiler* self) {
|
|||||||
consume(TK_ID);
|
consume(TK_ID);
|
||||||
if(mode() != EXEC_MODE) return SyntaxError("'label' is only available in EXEC_MODE");
|
if(mode() != EXEC_MODE) return SyntaxError("'label' is only available in EXEC_MODE");
|
||||||
c11_sv name = Token__sv(prev());
|
c11_sv name = Token__sv(prev());
|
||||||
bool ok = Ctx__add_label(ctx(), py_name2(name));
|
bool ok = Ctx__add_label(ctx(), py_namev(name));
|
||||||
if(!ok) return SyntaxError("label %q already exists", name);
|
if(!ok) return SyntaxError("label %q already exists", name);
|
||||||
consume(TK_EQ);
|
consume(TK_EQ);
|
||||||
consume_end_stmt();
|
consume_end_stmt();
|
||||||
@ -2568,7 +2568,7 @@ static Error* compile_stmt(Compiler* self) {
|
|||||||
case TK_ARROW:
|
case TK_ARROW:
|
||||||
consume(TK_ID);
|
consume(TK_ID);
|
||||||
if(mode() != EXEC_MODE) return SyntaxError("'goto' is only available in EXEC_MODE");
|
if(mode() != EXEC_MODE) return SyntaxError("'goto' is only available in EXEC_MODE");
|
||||||
py_Name name = py_name2(Token__sv(prev()));
|
py_Name name = py_namev(Token__sv(prev()));
|
||||||
Ctx__emit_(ctx(), OP_GOTO, name, prev()->line);
|
Ctx__emit_(ctx(), OP_GOTO, name, prev()->line);
|
||||||
consume_end_stmt();
|
consume_end_stmt();
|
||||||
break;
|
break;
|
||||||
|
@ -180,7 +180,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
|||||||
Function__ctor(ud, decl, frame->module);
|
Function__ctor(ud, decl, frame->module);
|
||||||
if(decl->nested) {
|
if(decl->nested) {
|
||||||
ud->closure = FastLocals__to_namedict(frame->locals, frame->locals_co);
|
ud->closure = FastLocals__to_namedict(frame->locals, frame->locals_co);
|
||||||
py_Name name = py_name2(c11_string__sv(decl->code.name));
|
py_Name name = py_namev(c11_string__sv(decl->code.name));
|
||||||
// capture itself to allow recursion
|
// capture itself to allow recursion
|
||||||
pk_NameDict__set(ud->closure, name, *SP());
|
pk_NameDict__set(ud->closure, name, *SP());
|
||||||
}
|
}
|
||||||
|
@ -85,27 +85,27 @@ void FuncDecl__add_starred_kwarg(FuncDecl* self, py_Name name) {
|
|||||||
self->starred_kwarg = index;
|
self->starred_kwarg = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
FuncDecl_ FuncDecl__build(const char* name,
|
FuncDecl_ FuncDecl__build(c11_sv name,
|
||||||
const char** args,
|
c11_sv* args,
|
||||||
int argc,
|
int argc,
|
||||||
const char* starred_arg,
|
c11_sv starred_arg,
|
||||||
const char** kwargs,
|
c11_sv* kwargs,
|
||||||
int kwargc,
|
int kwargc,
|
||||||
py_Ref kwdefaults, // a tuple contains default values
|
py_Ref kwdefaults, // a tuple contains default values
|
||||||
const char* starred_kwarg,
|
c11_sv starred_kwarg,
|
||||||
const char* docstring) {
|
const char* docstring) {
|
||||||
pk_SourceData_ source = pk_SourceData__rcnew("pass", "<bind>", EXEC_MODE, false);
|
pk_SourceData_ source = pk_SourceData__rcnew("pass", "<bind>", EXEC_MODE, false);
|
||||||
FuncDecl_ decl = FuncDecl__rcnew(source, (c11_sv){name, strlen(name)});
|
FuncDecl_ decl = FuncDecl__rcnew(source, name);
|
||||||
for(int i = 0; i < argc; i++) {
|
for(int i = 0; i < argc; i++) {
|
||||||
FuncDecl__add_arg(decl, py_name(args[i]));
|
FuncDecl__add_arg(decl, py_namev(args[i]));
|
||||||
}
|
}
|
||||||
if(starred_arg) { FuncDecl__add_starred_arg(decl, py_name(starred_arg)); }
|
if(starred_arg.size) { FuncDecl__add_starred_arg(decl, py_namev(starred_arg)); }
|
||||||
assert(py_istype(kwdefaults, tp_tuple));
|
assert(py_istype(kwdefaults, tp_tuple));
|
||||||
assert(py_tuple__len(kwdefaults) == kwargc);
|
assert(py_tuple__len(kwdefaults) == kwargc);
|
||||||
for(int i = 0; i < kwargc; i++) {
|
for(int i = 0; i < kwargc; i++) {
|
||||||
FuncDecl__add_kwarg(decl, py_name(kwargs[i]), py_tuple__getitem(kwdefaults, i));
|
FuncDecl__add_kwarg(decl, py_namev(kwargs[i]), py_tuple__getitem(kwdefaults, i));
|
||||||
}
|
}
|
||||||
if(starred_kwarg) FuncDecl__add_starred_kwarg(decl, py_name(starred_kwarg));
|
if(starred_kwarg.size) FuncDecl__add_starred_kwarg(decl, py_namev(starred_kwarg));
|
||||||
decl->docstring = docstring;
|
decl->docstring = docstring;
|
||||||
PK_DECREF(source);
|
PK_DECREF(source);
|
||||||
return decl;
|
return decl;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user