Revert "..."

This reverts commit d9b83fbeb70ed75079a538b77887269ed0cb58ef.
This commit is contained in:
blueloveTH 2023-07-22 22:44:27 +08:00
parent d9b83fbeb7
commit b0361b801a
9 changed files with 40 additions and 155 deletions

View File

@ -9,7 +9,7 @@ pipeline = [
["config.h", "export.h", "common.h", "memory.h", "vector.h", "str.h", "tuplelist.h", "namedict.h", "error.h", "lexer.h"], ["config.h", "export.h", "common.h", "memory.h", "vector.h", "str.h", "tuplelist.h", "namedict.h", "error.h", "lexer.h"],
["obj.h", "dict.h", "codeobject.h", "frame.h"], ["obj.h", "dict.h", "codeobject.h", "frame.h"],
["gc.h", "vm.h", "ceval.h", "expr.h", "compiler.h", "repl.h"], ["gc.h", "vm.h", "ceval.h", "expr.h", "compiler.h", "repl.h"],
["_generated.h", "cffi.h", "bindings.h", "iter.h", "base64.h", "random.h", "yaml.h", "re.h", "linalg.h", "easing.h", "io.h"], ["_generated.h", "cffi.h", "bindings.h", "iter.h", "base64.h", "random.h", "re.h", "linalg.h", "easing.h", "io.h"],
["pocketpy.h", "pocketpy_c.h"] ["pocketpy.h", "pocketpy_c.h"]
] ]

View File

@ -1,12 +0,0 @@
---
icon: package
label: yaml
---
### `yaml.loads(s) -> dict`
Decode a YAML string into a python object.
!!!
Only support a subset of YAML. The YAML to be parsed must have a equivalent JSON representation.
!!!

View File

@ -16,12 +16,25 @@ struct PrattRule{
Precedence precedence; Precedence precedence;
}; };
class Compiler: public CompilerBase { class Compiler {
inline static PrattRule rules[kTokenCount]; inline static PrattRule rules[kTokenCount];
std::unique_ptr<Lexer> lexer;
stack<CodeEmitContext> contexts; stack<CodeEmitContext> contexts;
VM* vm; VM* vm;
bool unknown_global_scope; // for eval/exec() call bool unknown_global_scope; // for eval/exec() call
bool used; bool used;
// for parsing token stream
int i = 0;
std::vector<Token> tokens;
const Token& prev() const{ return tokens.at(i-1); }
const Token& curr() const{ return tokens.at(i); }
const Token& next() const{ return tokens.at(i+1); }
const Token& err() const{
if(i >= tokens.size()) return prev();
return curr();
}
void advance(int delta=1) { i += delta; }
CodeEmitContext* ctx() { return &contexts.top(); } CodeEmitContext* ctx() { return &contexts.top(); }
CompileMode mode() const{ return lexer->src->mode; } CompileMode mode() const{ return lexer->src->mode; }
@ -32,7 +45,10 @@ class Compiler: public CompilerBase {
static void init_pratt_rules(); static void init_pratt_rules();
bool match(TokenIndex expected);
void consume(TokenIndex expected);
bool match_newlines_repl(); bool match_newlines_repl();
bool match_newlines(bool repl_throw=false); bool match_newlines(bool repl_throw=false);
bool match_end_stmt(); bool match_end_stmt();
void consume_end_stmt(); void consume_end_stmt();
@ -109,9 +125,17 @@ class Compiler: public CompilerBase {
PyObject* to_object(const TokenValue& value); PyObject* to_object(const TokenValue& value);
PyObject* read_literal(); PyObject* read_literal();
void SyntaxError(Str msg){ lexer->throw_err("SyntaxError", msg, err().line, err().start); }
void SyntaxError(){ lexer->throw_err("SyntaxError", "invalid syntax", err().line, err().start); }
void IndentationError(Str msg){ lexer->throw_err("IndentationError", msg, err().line, err().start); }
public: public:
Compiler(VM* vm, const Str& source, const Str& filename, CompileMode mode, bool unknown_global_scope=false); Compiler(VM* vm, const Str& source, const Str& filename, CompileMode mode, bool unknown_global_scope=false);
CodeObject_ compile(); CodeObject_ compile();
Compiler(const Compiler&) = delete;
Compiler& operator=(const Compiler&) = delete;
}; };
} // namespace pkpy } // namespace pkpy

View File

@ -141,44 +141,4 @@ struct Lexer {
std::vector<Token> run(); std::vector<Token> run();
}; };
class CompilerBase{
public:
std::unique_ptr<Lexer> lexer;
// for parsing token stream
int i = 0;
std::vector<Token> tokens;
const Token& prev() const{ return tokens.at(i-1); }
const Token& curr() const{ return tokens.at(i); }
const Token& next() const{ return tokens.at(i+1); }
const Token& err() const{
if(i >= tokens.size()) return prev();
return curr();
}
void advance(int delta=1) { i += delta; }
bool match(TokenIndex expected) {
if (curr().type != expected) return false;
advance();
return true;
}
void consume(TokenIndex expected) {
if (!match(expected)){
SyntaxError(
fmt("expected '", TK_STR(expected), "', got '", TK_STR(curr().type), "'")
);
}
}
void SyntaxError(Str msg){ lexer->throw_err("SyntaxError", msg, err().line, err().start); }
void SyntaxError(){ lexer->throw_err("SyntaxError", "invalid syntax", err().line, err().start); }
void IndentationError(Str msg){ lexer->throw_err("IndentationError", msg, err().line, err().start); }
CompilerBase(const CompilerBase&) = delete;
CompilerBase& operator=(const CompilerBase&) = delete;
CompilerBase() = default;
};
} // namespace pkpy } // namespace pkpy

View File

@ -12,7 +12,6 @@
#include "_generated.h" #include "_generated.h"
#include "vm.h" #include "vm.h"
#include "re.h" #include "re.h"
#include "yaml.h"
#include "random.h" #include "random.h"
#include "bindings.h" #include "bindings.h"

View File

@ -1,10 +0,0 @@
#pragma once
#include "cffi.h"
#include "lexer.h"
namespace pkpy{
void add_module_yaml(VM* vm);
} // namespace pkpy

View File

@ -92,6 +92,20 @@ namespace pkpy{
#undef NO_INFIX #undef NO_INFIX
} }
bool Compiler::match(TokenIndex expected) {
if (curr().type != expected) return false;
advance();
return true;
}
void Compiler::consume(TokenIndex expected) {
if (!match(expected)){
SyntaxError(
fmt("expected '", TK_STR(expected), "', got '", TK_STR(curr().type), "'")
);
}
}
bool Compiler::match_newlines_repl(){ bool Compiler::match_newlines_repl(){
return match_newlines(mode()==REPL_MODE); return match_newlines(mode()==REPL_MODE);
} }

View File

@ -1489,7 +1489,6 @@ void VM::post_init(){
add_module_random(this); add_module_random(this);
add_module_base64(this); add_module_base64(this);
add_module_timeit(this); add_module_timeit(this);
add_module_yaml(this);
for(const char* name: {"this", "functools", "collections", "heapq", "bisect", "pickle", "_long"}){ for(const char* name: {"this", "functools", "collections", "heapq", "bisect", "pickle", "_long"}){
_lazy_modules[name] = kPythonLibs[name]; _lazy_modules[name] = kPythonLibs[name];

View File

@ -1,89 +0,0 @@
#include "pocketpy/yaml.h"
namespace pkpy{
class YAMLCompiler: public CompilerBase{
public:
VM* vm;
YAMLCompiler(VM* vm, const Str& s): vm(vm) {
auto src = std::make_shared<SourceData>(s, "<yaml>", JSON_MODE);
this->lexer = std::make_unique<Lexer>(src);
}
PyObject* EXPR(bool* valid_key){
// BASIC: True False None @str @num
// CONTAINER: [] {}
*valid_key = false;
switch(curr().type){
case TK("True"): advance(); return vm->True; break;
case TK("False"): advance(); return vm->False; break;
case TK("None"): advance(); return vm->None; break;
case TK("@num"):{
advance();
TokenValue value = prev().value;
if(std::holds_alternative<i64>(value)){
return VAR(std::get<i64>(value));
}else if(std::holds_alternative<f64>(value)){
return VAR(std::get<f64>(value));
}
FATAL_ERROR();
}
case TK("@str"):
advance();
*valid_key = true;
return VAR(std::get<Str>(prev().value));
case TK("@id"):
*valid_key = true;
advance();
return VAR(prev().sv());
case TK("["): case TK("{"): {
// parse the whole line as json
return NULL;
}
default: SyntaxError();
return NULL;
}
}
PyObject* compile_block(){
consume(TK(":"));
if(curr().type!=TK("@eol") && curr().type!=TK("@eof")){
bool _;
return EXPR(&_); // inline block
}
PyObject* block = VAR(Dict(vm));
Dict& d = PK_OBJ_GET(Dict, block);
consume(TK("@indent"));
while (curr().type != TK("@dedent")) {
bool valid_key;
PyObject* key = EXPR(&valid_key);
if(!valid_key) SyntaxError();
}
consume(TK("@dedent"));
}
Dict compile(){
tokens = lexer->run();
Dict d(vm);
advance(); // skip @sof, so prev() is always valid
while (!match(TK("@eof"))) {
}
return d;
}
};
void add_module_yaml(VM* vm){
PyObject* mod = vm->new_module("yaml");
vm->bind(mod, "loads(s: str) -> dict", [](VM* vm, ArgsView args){
const Str& s = CAST(Str&, args[0]);
YAMLCompiler compiler(vm, s);
return VAR(compiler.compile());
});
}
} // namespace pkpy