br-codex-xx 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- br_codex_xx-0.1.0/LICENSE +21 -0
- br_codex_xx-0.1.0/MANIFEST.in +4 -0
- br_codex_xx-0.1.0/PKG-INFO +74 -0
- br_codex_xx-0.1.0/README.md +63 -0
- br_codex_xx-0.1.0/bpp.cpp +55 -0
- br_codex_xx-0.1.0/bpp_lang/__init__.py +3 -0
- br_codex_xx-0.1.0/bpp_lang/cli.py +20 -0
- br_codex_xx-0.1.0/br_codex_xx.egg-info/PKG-INFO +74 -0
- br_codex_xx-0.1.0/br_codex_xx.egg-info/SOURCES.txt +13 -0
- br_codex_xx-0.1.0/br_codex_xx.egg-info/dependency_links.txt +1 -0
- br_codex_xx-0.1.0/br_codex_xx.egg-info/entry_points.txt +2 -0
- br_codex_xx-0.1.0/br_codex_xx.egg-info/top_level.txt +1 -0
- br_codex_xx-0.1.0/pyproject.toml +14 -0
- br_codex_xx-0.1.0/setup.cfg +4 -0
- br_codex_xx-0.1.0/setup.py +62 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 brawlstarsarthurgg415-byte
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: br-codex_xx
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Interpretador da linguagem B++ em portugues
|
|
5
|
+
Author: Thurzingg
|
|
6
|
+
Requires-Python: >=3.8
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Dynamic: license-file
|
|
10
|
+
Dynamic: requires-python
|
|
11
|
+
|
|
12
|
+
# B++
|
|
13
|
+
|
|
14
|
+
B++ e uma linguagem de programacao em portugues, interpretada por um motor escrito em C++.
|
|
15
|
+
|
|
16
|
+
## Requisitos
|
|
17
|
+
|
|
18
|
+
- Python 3.8 ou superior para instalar o pacote
|
|
19
|
+
- `g++` com suporte a C++17 para construir o pacote
|
|
20
|
+
|
|
21
|
+
## Instalar pelo PyPI
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
python -m pip install b-rr
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
A instalacao compila automaticamente `bpp.cpp` e cria o comando `bpp`.
|
|
28
|
+
|
|
29
|
+
## Executar um arquivo B++
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
bpp sistema.bpp
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Exemplo minimo:
|
|
36
|
+
|
|
37
|
+
```bpp
|
|
38
|
+
texto nome = "Ana";
|
|
39
|
+
inteiro idade = 20;
|
|
40
|
+
|
|
41
|
+
se (idade >= 18) {
|
|
42
|
+
escreva("Ola, {nome}. Voce e maior de idade.");
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
A sintaxe inclui tipos `inteiro`, `decimal`, `texto`, `booleano` e `lista`; `escreva`, `leia`, `adicionar`, `se`, `senao se`, `senao`, `enquanto`, `para`, `funcao`, `retorne` e comentarios `//`.
|
|
47
|
+
|
|
48
|
+
## Compilar localmente
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
g++ -std=c++17 -O2 -Wall -Wextra -Wpedantic bpp.cpp -o bpp
|
|
52
|
+
./bpp sistema.bpp
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Construir e publicar no PyPI
|
|
56
|
+
|
|
57
|
+
Crie uma conta no PyPI e configure um token de API no `twine` antes do upload. Depois execute, na raiz do projeto:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
python -m pip install --upgrade build twine
|
|
61
|
+
rm -rf build dist *.egg-info
|
|
62
|
+
python -m build
|
|
63
|
+
python -m twine check dist/*
|
|
64
|
+
python -m twine upload dist/*
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Para testar primeiro no TestPyPI:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
python -m twine upload --repository testpypi dist/*
|
|
71
|
+
python -m pip install --index-url https://test.pypi.org/simple/ b-rr
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
O comando `twine upload` solicitará o usuário e o token, caso eles não estejam configurados por variáveis ou por um arquivo `.pypirc`.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# B++
|
|
2
|
+
|
|
3
|
+
B++ e uma linguagem de programacao em portugues, interpretada por um motor escrito em C++.
|
|
4
|
+
|
|
5
|
+
## Requisitos
|
|
6
|
+
|
|
7
|
+
- Python 3.8 ou superior para instalar o pacote
|
|
8
|
+
- `g++` com suporte a C++17 para construir o pacote
|
|
9
|
+
|
|
10
|
+
## Instalar pelo PyPI
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
python -m pip install b-rr
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
A instalacao compila automaticamente `bpp.cpp` e cria o comando `bpp`.
|
|
17
|
+
|
|
18
|
+
## Executar um arquivo B++
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
bpp sistema.bpp
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Exemplo minimo:
|
|
25
|
+
|
|
26
|
+
```bpp
|
|
27
|
+
texto nome = "Ana";
|
|
28
|
+
inteiro idade = 20;
|
|
29
|
+
|
|
30
|
+
se (idade >= 18) {
|
|
31
|
+
escreva("Ola, {nome}. Voce e maior de idade.");
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
A sintaxe inclui tipos `inteiro`, `decimal`, `texto`, `booleano` e `lista`; `escreva`, `leia`, `adicionar`, `se`, `senao se`, `senao`, `enquanto`, `para`, `funcao`, `retorne` e comentarios `//`.
|
|
36
|
+
|
|
37
|
+
## Compilar localmente
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
g++ -std=c++17 -O2 -Wall -Wextra -Wpedantic bpp.cpp -o bpp
|
|
41
|
+
./bpp sistema.bpp
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Construir e publicar no PyPI
|
|
45
|
+
|
|
46
|
+
Crie uma conta no PyPI e configure um token de API no `twine` antes do upload. Depois execute, na raiz do projeto:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
python -m pip install --upgrade build twine
|
|
50
|
+
rm -rf build dist *.egg-info
|
|
51
|
+
python -m build
|
|
52
|
+
python -m twine check dist/*
|
|
53
|
+
python -m twine upload dist/*
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Para testar primeiro no TestPyPI:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
python -m twine upload --repository testpypi dist/*
|
|
60
|
+
python -m pip install --index-url https://test.pypi.org/simple/ b-rr
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
O comando `twine upload` solicitará o usuário e o token, caso eles não estejam configurados por variáveis ou por um arquivo `.pypirc`.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#include <algorithm>
|
|
2
|
+
#include <cctype>
|
|
3
|
+
#include <fstream>
|
|
4
|
+
#include <functional>
|
|
5
|
+
#include <iomanip>
|
|
6
|
+
#include <iostream>
|
|
7
|
+
#include <memory>
|
|
8
|
+
#include <sstream>
|
|
9
|
+
#include <stdexcept>
|
|
10
|
+
#include <string>
|
|
11
|
+
#include <unordered_map>
|
|
12
|
+
#include <utility>
|
|
13
|
+
#include <variant>
|
|
14
|
+
#include <vector>
|
|
15
|
+
using namespace std;
|
|
16
|
+
|
|
17
|
+
struct Callable; struct Value;
|
|
18
|
+
using List = shared_ptr<vector<Value>>;
|
|
19
|
+
using Data = variant<monostate,bool,long long,double,string,List,shared_ptr<Callable>>;
|
|
20
|
+
struct Value { Data data; Value()=default; template<class T> Value(T v):data(move(v)){} bool null()const{return holds_alternative<monostate>(data);} double number()const{if(holds_alternative<long long>(data))return static_cast<double>(get<long long>(data));if(holds_alternative<double>(data))return get<double>(data);throw runtime_error("valor nao e numerico");} bool truth()const{if(null())return false;if(holds_alternative<bool>(data))return get<bool>(data);if(holds_alternative<long long>(data))return get<long long>(data)!=0;if(holds_alternative<double>(data))return get<double>(data)!=0;if(holds_alternative<string>(data))return !get<string>(data).empty();if(holds_alternative<List>(data))return !get<List>(data)->empty();return true;} string text()const;};
|
|
21
|
+
struct Error:runtime_error{using runtime_error::runtime_error;};
|
|
22
|
+
string Value::text()const{if(null())return "nulo";if(holds_alternative<bool>(data))return get<bool>(data)?"verdadeiro":"falso";if(holds_alternative<long long>(data))return to_string(get<long long>(data));if(holds_alternative<double>(data)){ostringstream o;o<<setprecision(15)<<get<double>(data);return o.str();}if(holds_alternative<string>(data))return get<string>(data);if(holds_alternative<List>(data)){string s="[";auto& v=*get<List>(data);for(size_t i=0;i<v.size();++i){if(i)s+=", ";s+=v[i].text();}return s+"]";}return "<funcao>";}
|
|
23
|
+
bool same(const Value&a,const Value&b){if((holds_alternative<long long>(a.data)||holds_alternative<double>(a.data))&&(holds_alternative<long long>(b.data)||holds_alternative<double>(b.data)))return a.number()==b.number();if(a.data.index()!=b.data.index())return false;if(a.null())return true;if(holds_alternative<List>(a.data))return get<List>(a.data)==get<List>(b.data);if(holds_alternative<shared_ptr<Callable>>(a.data))return get<shared_ptr<Callable>>(a.data)==get<shared_ptr<Callable>>(b.data);return a.data==b.data;}
|
|
24
|
+
struct Env {unordered_map<string,Value> vars;shared_ptr<Env> parent;explicit Env(shared_ptr<Env> p=nullptr):parent(move(p)){}void define(string n,Value v){vars[move(n)]=move(v);}Value get(const string&n)const{auto i=vars.find(n);if(i!=vars.end())return i->second;if(parent)return parent->get(n);throw Error("variavel nao definida: "+n);}void set(const string&n,Value v){auto i=vars.find(n);if(i!=vars.end()){i->second=move(v);return;}if(parent){parent->set(n,move(v));return;}throw Error("variavel nao definida: "+n);}};
|
|
25
|
+
|
|
26
|
+
enum class T{End,Word,Num,Str,Plus,Minus,Star,Slash,Mod,LP,RP,LB,RB,LS,RS,Comma,Semi,Assign,Eq,Ne,Gt,Lt,Ge,Le,Not,And,Or};
|
|
27
|
+
struct Token{T type;string value;int line;};
|
|
28
|
+
class Lexer {string s;size_t p=0;int line=1;char peek()const{return p<s.size()?s[p]:0;}char take(){return p<s.size()?s[p++]:0;}public:explicit Lexer(string x):s(move(x)){}vector<Token> scan(){vector<Token> r;auto add=[&](T t,string v){r.push_back({t,move(v),line});};while(p<s.size()){char c=take();if(c==' '||c=='\t'||c=='\r')continue;if(c=='\n'){line++;continue;}if(c=='/'&&peek()=='/'){while(peek()&&peek()!='\n')take();continue;}if(isalpha((unsigned char)c)||c=='_'){string w(1,c);while(isalnum((unsigned char)peek())||peek()=='_')w+=take();add(T::Word,w);continue;}if(isdigit((unsigned char)c)){string n(1,c);while(isdigit((unsigned char)peek())||peek()=='.')n+=take();add(T::Num,n);continue;}if(c=='"'){string x;while(peek()&&peek()!='"'){if(peek()=='\\'){take();char e=take();x+=e=='n'?'\n':e=='t'?'\t':e;}else x+=take();}if(!peek())throw Error("texto nao terminado");take();add(T::Str,x);continue;}T t;string v(1,c);switch(c){case '+':t=T::Plus;break;case '-':t=T::Minus;break;case '*':t=T::Star;break;case '/':t=T::Slash;break;case '%':t=T::Mod;break;case '(':t=T::LP;break;case ')':t=T::RP;break;case '{':t=T::LB;break;case '}':t=T::RB;break;case '[':t=T::LS;break;case ']':t=T::RS;break;case ',':t=T::Comma;break;case ';':t=T::Semi;break;case '!':t=peek()=='='?(take(),v+="=",T::Ne):T::Not;break;case '=':t=peek()=='='?(take(),v+="=",T::Eq):T::Assign;break;case '>':t=peek()=='='?(take(),v+="=",T::Ge):T::Gt;break;case '<':t=peek()=='='?(take(),v+="=",T::Le):T::Lt;break;default:throw Error("caractere invalido na linha "+to_string(line));}add(t,v);}r.push_back({T::End,"",line});return r;}};
|
|
29
|
+
|
|
30
|
+
struct Interpreter;struct Expr{virtual~Expr()=default;virtual Value eval(Interpreter&)=0;virtual void put(Interpreter&,Value){throw Error("expressao nao pode receber atribuicao");}};struct Stmt{virtual~Stmt()=default;virtual void run(Interpreter&)=0;};using EP=unique_ptr<Expr>;using SP=unique_ptr<Stmt>;using Program=vector<SP>;
|
|
31
|
+
struct Callable{virtual~Callable()=default;virtual Value call(Interpreter&,const vector<Value>&)=0;};struct Return:exception{Value value;explicit Return(Value v):value(move(v)){}};
|
|
32
|
+
struct Lit:Expr{Value v;explicit Lit(Value x):v(move(x)){}Value eval(Interpreter&)override{return v;}};struct Var:Expr{string n;explicit Var(string x):n(move(x)){}Value eval(Interpreter&)override;void put(Interpreter&,Value)override;};struct Idx:Expr{EP a,b;Idx(EP x,EP y):a(move(x)),b(move(y)){}Value eval(Interpreter&)override;void put(Interpreter&,Value)override;};struct Unary:Expr{T op;EP x;Unary(T o,EP e):op(o),x(move(e)){}Value eval(Interpreter&)override;};struct Bin:Expr{EP a,b;T op;Bin(EP x,T o,EP y):a(move(x)),b(move(y)),op(o){}Value eval(Interpreter&)override;};struct Call:Expr{EP f;vector<EP> args;Call(EP x,vector<EP> y):f(move(x)),args(move(y)){}Value eval(Interpreter&)override;};struct Array:Expr{vector<EP> x;explicit Array(vector<EP> y):x(move(y)){}Value eval(Interpreter&)override;};struct Set:Expr{EP a,b;Set(EP x,EP y):a(move(x)),b(move(y)){}Value eval(Interpreter&i)override{Value v=b->eval(i);a->put(i,v);return v;}};
|
|
33
|
+
struct ExprStmt:Stmt{EP x;explicit ExprStmt(EP e):x(move(e)){}void run(Interpreter&i)override{x->eval(i);}};struct Decl:Stmt{string type,n;EP x;Decl(string t,string y,EP e):type(move(t)),n(move(y)),x(move(e)){}void run(Interpreter&)override;};struct Block:Stmt{Program p;explicit Block(Program x):p(move(x)){}void run(Interpreter&)override;};struct If:Stmt{EP c;SP yes,no;vector<pair<EP,SP>> more;void run(Interpreter&)override;};struct While:Stmt{EP c;SP b;void run(Interpreter&)override;};struct For:Stmt{SP init;EP c,step;SP b;void run(Interpreter&)override;};struct Print:Stmt{vector<EP>x;explicit Print(vector<EP>y):x(move(y)){}void run(Interpreter&)override;};struct Read:Stmt{vector<string>x;explicit Read(vector<string>y):x(move(y)){}void run(Interpreter&)override;};struct Ret:Stmt{EP x;explicit Ret(EP e):x(move(e)){}void run(Interpreter&i)override{throw Return(x?x->eval(i):Value());}};struct Add:Stmt{string n;EP x;Add(string y,EP e):n(move(y)),x(move(e)){}void run(Interpreter&)override;};struct Func:Stmt{string n;vector<string>args;SP b;void run(Interpreter&)override;};
|
|
34
|
+
struct User:Callable{vector<string>args;SP*body;shared_ptr<Env> closure;User(vector<string>a,SP*b,shared_ptr<Env>e):args(move(a)),body(b),closure(move(e)){}Value call(Interpreter&,const vector<Value>&)override;};
|
|
35
|
+
struct Interpreter{shared_ptr<Env> globals=make_shared<Env>(),env=globals;static string interpolate(string s,shared_ptr<Env>e){size_t p=0;while((p=s.find('{',p))!=string::npos){auto q=s.find('}',p);if(q==string::npos)break;string n=s.substr(p+1,q-p-1);try{s.replace(p,q-p+1,e->get(n).text());p+=n.size();}catch(...){p=q+1;}}return s;}void run(const Program&p){for(auto&x:p)x->run(*this);}};
|
|
36
|
+
Value Var::eval(Interpreter&i){return i.env->get(n);}void Var::put(Interpreter&i,Value v){i.env->set(n,move(v));}Value Idx::eval(Interpreter&i){Value v=a->eval(i);Value index=b->eval(i);if(!holds_alternative<long long>(index.data)||!holds_alternative<List>(v.data))throw Error("indice deve ser inteiro e a expressao deve ser uma lista");long long n=get<long long>(index.data);if(n<0||static_cast<unsigned long long>(n)>=get<List>(v.data)->size())throw Error("indice invalido");return (*get<List>(v.data))[static_cast<size_t>(n)];}void Idx::put(Interpreter&i,Value v){Value a1=a->eval(i);Value index=b->eval(i);if(!holds_alternative<long long>(index.data)||!holds_alternative<List>(a1.data))throw Error("indice deve ser inteiro e a expressao deve ser uma lista");long long n=get<long long>(index.data);if(n<0||static_cast<unsigned long long>(n)>=get<List>(a1.data)->size())throw Error("indice invalido");(*get<List>(a1.data))[static_cast<size_t>(n)]=move(v);}
|
|
37
|
+
Value Unary::eval(Interpreter&i){Value v=x->eval(i);if(op==T::Not)return Value(!v.truth());if(op==T::Minus)return holds_alternative<long long>(v.data)?Value(-get<long long>(v.data)):Value(-v.number());return v;}
|
|
38
|
+
Value Bin::eval(Interpreter&i){
|
|
39
|
+
Value left=a->eval(i); if(op==T::And&&!left.truth())return Value(false); if(op==T::Or&&left.truth())return Value(true); Value right=b->eval(i);
|
|
40
|
+
switch(op){case T::And:return Value(left.truth()&&right.truth());case T::Or:return Value(left.truth()||right.truth());case T::Plus:if(holds_alternative<string>(left.data)||holds_alternative<string>(right.data))return Value(left.text()+right.text());return holds_alternative<long long>(left.data)&&holds_alternative<long long>(right.data)?Value(get<long long>(left.data)+get<long long>(right.data)):Value(left.number()+right.number());case T::Minus:return holds_alternative<long long>(left.data)&&holds_alternative<long long>(right.data)?Value(get<long long>(left.data)-get<long long>(right.data)):Value(left.number()-right.number());case T::Star:return holds_alternative<long long>(left.data)&&holds_alternative<long long>(right.data)?Value(get<long long>(left.data)*get<long long>(right.data)):Value(left.number()*right.number());case T::Slash:if(right.number()==0)throw Error("divisao por zero");return Value(left.number()/right.number());case T::Mod:if(!holds_alternative<long long>(left.data)||!holds_alternative<long long>(right.data))throw Error("% exige operandos inteiros");if(get<long long>(right.data)==0)throw Error("divisao por zero");return Value(get<long long>(left.data)%get<long long>(right.data));case T::Eq:return Value(same(left,right));case T::Ne:return Value(!same(left,right));case T::Gt:return Value(left.number()>right.number());case T::Lt:return Value(left.number()<right.number());case T::Ge:return Value(left.number()>=right.number());case T::Le:return Value(left.number()<=right.number());default:throw Error("operador invalido");}}
|
|
41
|
+
Value Call::eval(Interpreter&i){Value function=f->eval(i);if(!holds_alternative<shared_ptr<Callable>>(function.data))throw Error("valor nao e uma funcao");vector<Value>v;for(auto&x:args)v.push_back(x->eval(i));return get<shared_ptr<Callable>>(function.data)->call(i,v);}
|
|
42
|
+
Value Array::eval(Interpreter&i){auto v=make_shared<vector<Value>>();for(auto&item:x)v->push_back(item->eval(i));return Value(v);}
|
|
43
|
+
void Decl::run(Interpreter&i){i.env->define(n,x?x->eval(i):Value());}void Block::run(Interpreter&i){auto old=i.env;i.env=make_shared<Env>(old);try{for(auto&x:p)x->run(i);}catch(...){i.env=old;throw;}i.env=old;}
|
|
44
|
+
void If::run(Interpreter&i){if(c->eval(i).truth())yes->run(i);else{for(auto&x:more)if(x.first->eval(i).truth()){x.second->run(i);return;}if(no)no->run(i);}}void While::run(Interpreter&i){while(c->eval(i).truth())b->run(i);}void For::run(Interpreter&i){auto old=i.env;i.env=make_shared<Env>(old);try{if(init)init->run(i);while(!c||c->eval(i).truth()){b->run(i);if(step)step->eval(i);}}catch(...){i.env=old;throw;}i.env=old;}
|
|
45
|
+
void Print::run(Interpreter&i){for(size_t n=0;n<x.size();++n){if(n)cout<<' ';cout<<Interpreter::interpolate(x[n]->eval(i).text(),i.env);}cout<<'\n';}void Read::run(Interpreter&i){string s;for(auto&n:x){if(!(cin>>s))throw Error("falha na leitura");Value old=i.env->get(n);if(holds_alternative<long long>(old.data))i.env->set(n,stoll(s));else if(holds_alternative<double>(old.data))i.env->set(n,stod(s));else if(holds_alternative<bool>(old.data))i.env->set(n,s=="verdadeiro"||s=="true"||s=="1");else i.env->set(n,s);}}void Add::run(Interpreter&i){Value v=i.env->get(n);if(!holds_alternative<List>(v.data))throw Error(n+" nao e uma lista");get<List>(v.data)->push_back(x->eval(i));}void Func::run(Interpreter&i){i.env->define(n,Value(make_shared<User>(args,&b,i.env)));}
|
|
46
|
+
Value User::call(Interpreter&i,const vector<Value>&v){if(v.size()!=args.size())throw Error("quantidade incorreta de argumentos");auto old=i.env;i.env=make_shared<Env>(closure);for(size_t n=0;n<args.size();++n)i.env->define(args[n],v[n]);try{(*body)->run(i);}catch(const Return&r){i.env=old;return r.value;}i.env=old;return Value();}
|
|
47
|
+
|
|
48
|
+
class Parser{vector<Token>t;size_t p=0;Token&peek(){return t[p];}Token prev(){return t[p-1];}bool check(T x){return peek().type==x;}bool word(string x){return check(T::Word)&&peek().value==x;}Token take(){if(!check(T::End))++p;return prev();}bool match(T x){if(!check(x))return false;take();return true;}bool matchWord(string x){if(!word(x))return false;take();return true;}void need(T x,string m){if(!match(x))throw Error(m+" na linha "+to_string(peek().line));}string name(string m){if(!check(T::Word))throw Error(m);return take().value;}SP stmt();SP decl();Program block();EP expr();EP assign();EP logicOr();EP logicAnd();EP equality();EP compare();EP term();EP factor();EP unary();EP primary();public:explicit Parser(vector<Token>x):t(move(x)){}Program parse(){Program r;while(!check(T::End))r.push_back(decl());return r;}};
|
|
49
|
+
Program Parser::block(){Program r;while(!check(T::RB)&&!check(T::End))r.push_back(decl());need(T::RB,"esperado '}'");return r;}
|
|
50
|
+
SP Parser::decl(){if(matchWord("funcao")){auto f=make_unique<Func>();f->n=name("nome esperado");need(T::LP,"esperado '('");if(!check(T::RP)){do f->args.push_back(name("parametro esperado"));while(match(T::Comma));}need(T::RP,"esperado ')'");need(T::LB,"esperado '{'");f->b=make_unique<Block>(block());return f;}if(word("inteiro")||word("decimal")||word("texto")||word("booleano")||word("lista")){take();string n=name("nome de variavel esperado");EP x;if(match(T::Assign))x=expr();need(T::Semi,"esperado ';'");return make_unique<Decl>("",n,move(x));}return stmt();}
|
|
51
|
+
SP Parser::stmt(){if(matchWord("escreva")){need(T::LP,"esperado '('");vector<EP>x;if(!check(T::RP)){do x.push_back(expr());while(match(T::Comma));}need(T::RP,"esperado ')'");need(T::Semi,"esperado ';'");return make_unique<Print>(move(x));}if(matchWord("leia")){need(T::LP,"esperado '('");vector<string>x;do x.push_back(name("variavel esperada"));while(match(T::Comma));need(T::RP,"esperado ')'");need(T::Semi,"esperado ';'");return make_unique<Read>(move(x));}if(matchWord("adicionar")){need(T::LP,"esperado '('");string n=name("lista esperada");need(T::Comma,"esperado ','");auto x=expr();need(T::RP,"esperado ')'");need(T::Semi,"esperado ';'");return make_unique<Add>(n,move(x));}if(matchWord("retorne")){EP x;if(!check(T::Semi))x=expr();need(T::Semi,"esperado ';'");return make_unique<Ret>(move(x));}if(matchWord("se")){auto q=make_unique<If>();need(T::LP,"esperado '('");q->c=expr();need(T::RP,"esperado ')'");need(T::LB,"esperado '{'");q->yes=make_unique<Block>(block());while(matchWord("senao")){if(matchWord("se")){need(T::LP,"esperado '('");auto c=expr();need(T::RP,"esperado ')'");need(T::LB,"esperado '{'");q->more.emplace_back(move(c),make_unique<Block>(block()));}else{need(T::LB,"esperado '{'");q->no=make_unique<Block>(block());break;}}return q;}if(matchWord("enquanto")){need(T::LP,"esperado '('");auto c=expr();need(T::RP,"esperado ')'");need(T::LB,"esperado '{'");auto q=make_unique<While>();q->c=move(c);q->b=make_unique<Block>(block());return q;}if(matchWord("para")){need(T::LP,"esperado '('");SP init;if(!check(T::Semi))init=decl();else take();EP c;if(!check(T::Semi))c=expr();need(T::Semi,"esperado ';'");EP step;if(!check(T::RP))step=expr();need(T::RP,"esperado ')'");need(T::LB,"esperado '{'");auto q=make_unique<For>();q->init=move(init);q->c=move(c);q->step=move(step);q->b=make_unique<Block>(block());return q;}if(match(T::LB))return make_unique<Block>(block());auto q=make_unique<ExprStmt>(expr());need(T::Semi,"esperado ';'");return q;}
|
|
52
|
+
EP Parser::expr(){return assign();}EP Parser::assign(){auto x=logicOr();if(match(T::Assign))x=make_unique<Set>(move(x),assign());return x;}EP Parser::logicOr(){auto x=logicAnd();while(matchWord("ou"))x=make_unique<Bin>(move(x),T::Or,logicAnd());return x;}EP Parser::logicAnd(){auto x=equality();while(matchWord("e"))x=make_unique<Bin>(move(x),T::And,equality());return x;}EP Parser::equality(){auto x=compare();while(check(T::Eq)||check(T::Ne)){T o=take().type;x=make_unique<Bin>(move(x),o,compare());}return x;}EP Parser::compare(){auto x=term();while(check(T::Gt)||check(T::Lt)||check(T::Ge)||check(T::Le)){T o=take().type;x=make_unique<Bin>(move(x),o,term());}return x;}EP Parser::term(){auto x=factor();while(check(T::Plus)||check(T::Minus)){T o=take().type;x=make_unique<Bin>(move(x),o,factor());}return x;}EP Parser::factor(){auto x=unary();while(check(T::Star)||check(T::Slash)||check(T::Mod)){T o=take().type;x=make_unique<Bin>(move(x),o,unary());}return x;}EP Parser::unary(){if(check(T::Not)||check(T::Minus)){T o=take().type;return make_unique<Unary>(o,unary());}return primary();}
|
|
53
|
+
EP Parser::primary(){EP x;if(match(T::Num)){string n=prev().value;x=make_unique<Lit>(n.find('.')==string::npos?Value(stoll(n)):Value(stod(n)));}else if(match(T::Str))x=make_unique<Lit>(prev().value);else if(matchWord("verdadeiro"))x=make_unique<Lit>(true);else if(matchWord("falso"))x=make_unique<Lit>(false);else if(match(T::LP)){x=expr();need(T::RP,"esperado ')'");}else if(match(T::LS)){vector<EP>v;if(!check(T::RS)){do v.push_back(expr());while(match(T::Comma));}need(T::RS,"esperado ']'");x=make_unique<Array>(move(v));}else x=make_unique<Var>(name("expressao esperada"));while(true){if(match(T::LS)){auto i=expr();need(T::RS,"esperado ']'");x=make_unique<Idx>(move(x),move(i));}else if(match(T::LP)){vector<EP>a;if(!check(T::RP)){do a.push_back(expr());while(match(T::Comma));}need(T::RP,"esperado ')'");x=make_unique<Call>(move(x),move(a));}else break;}return x;}
|
|
54
|
+
struct Native:Callable{function<Value(Interpreter&,const vector<Value>&)>f;explicit Native(function<Value(Interpreter&,const vector<Value>&)>x):f(move(x)){}Value call(Interpreter&i,const vector<Value>&a)override{return f(i,a);}};
|
|
55
|
+
int main(int argc,char**argv){if(argc!=2){cerr<<"Uso: bpp <arquivo.bpp>\n";return 2;}try{ifstream in(argv[1]);if(!in)throw Error("nao foi possivel abrir o arquivo");string s((istreambuf_iterator<char>(in)),{});Interpreter i;i.globals->define("comprimento",Value(make_shared<Native>([](Interpreter&,const vector<Value>&a){if(a.size()!=1)throw Error("comprimento exige um argumento");if(holds_alternative<List>(a[0].data))return Value((long long)get<List>(a[0].data)->size());if(holds_alternative<string>(a[0].data))return Value((long long)get<string>(a[0].data).size());throw Error("comprimento aceita lista ou texto");})));i.run(Parser(Lexer(s).scan()).parse());}catch(const exception&e){cerr<<"B++ erro: "<<e.what()<<'\n';return 1;}}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
import subprocess
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def main() -> int:
|
|
7
|
+
if len(sys.argv) != 2:
|
|
8
|
+
print("Uso: bpp <arquivo.bpp>", file=sys.stderr)
|
|
9
|
+
return 2
|
|
10
|
+
executable = Path(__file__).with_name("bin") / "bpp"
|
|
11
|
+
try:
|
|
12
|
+
result = subprocess.run([str(executable), sys.argv[1]], check=False)
|
|
13
|
+
except OSError as error:
|
|
14
|
+
print(f"bpp: nao foi possivel iniciar o interpretador: {error}", file=sys.stderr)
|
|
15
|
+
return 1
|
|
16
|
+
return result.returncode
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
if __name__ == "__main__":
|
|
20
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: br-codex_xx
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Interpretador da linguagem B++ em portugues
|
|
5
|
+
Author: Thurzingg
|
|
6
|
+
Requires-Python: >=3.8
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Dynamic: license-file
|
|
10
|
+
Dynamic: requires-python
|
|
11
|
+
|
|
12
|
+
# B++
|
|
13
|
+
|
|
14
|
+
B++ e uma linguagem de programacao em portugues, interpretada por um motor escrito em C++.
|
|
15
|
+
|
|
16
|
+
## Requisitos
|
|
17
|
+
|
|
18
|
+
- Python 3.8 ou superior para instalar o pacote
|
|
19
|
+
- `g++` com suporte a C++17 para construir o pacote
|
|
20
|
+
|
|
21
|
+
## Instalar pelo PyPI
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
python -m pip install b-rr
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
A instalacao compila automaticamente `bpp.cpp` e cria o comando `bpp`.
|
|
28
|
+
|
|
29
|
+
## Executar um arquivo B++
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
bpp sistema.bpp
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Exemplo minimo:
|
|
36
|
+
|
|
37
|
+
```bpp
|
|
38
|
+
texto nome = "Ana";
|
|
39
|
+
inteiro idade = 20;
|
|
40
|
+
|
|
41
|
+
se (idade >= 18) {
|
|
42
|
+
escreva("Ola, {nome}. Voce e maior de idade.");
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
A sintaxe inclui tipos `inteiro`, `decimal`, `texto`, `booleano` e `lista`; `escreva`, `leia`, `adicionar`, `se`, `senao se`, `senao`, `enquanto`, `para`, `funcao`, `retorne` e comentarios `//`.
|
|
47
|
+
|
|
48
|
+
## Compilar localmente
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
g++ -std=c++17 -O2 -Wall -Wextra -Wpedantic bpp.cpp -o bpp
|
|
52
|
+
./bpp sistema.bpp
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Construir e publicar no PyPI
|
|
56
|
+
|
|
57
|
+
Crie uma conta no PyPI e configure um token de API no `twine` antes do upload. Depois execute, na raiz do projeto:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
python -m pip install --upgrade build twine
|
|
61
|
+
rm -rf build dist *.egg-info
|
|
62
|
+
python -m build
|
|
63
|
+
python -m twine check dist/*
|
|
64
|
+
python -m twine upload dist/*
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Para testar primeiro no TestPyPI:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
python -m twine upload --repository testpypi dist/*
|
|
71
|
+
python -m pip install --index-url https://test.pypi.org/simple/ b-rr
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
O comando `twine upload` solicitará o usuário e o token, caso eles não estejam configurados por variáveis ou por um arquivo `.pypirc`.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
MANIFEST.in
|
|
3
|
+
README.md
|
|
4
|
+
bpp.cpp
|
|
5
|
+
pyproject.toml
|
|
6
|
+
setup.py
|
|
7
|
+
bpp_lang/__init__.py
|
|
8
|
+
bpp_lang/cli.py
|
|
9
|
+
br_codex_xx.egg-info/PKG-INFO
|
|
10
|
+
br_codex_xx.egg-info/SOURCES.txt
|
|
11
|
+
br_codex_xx.egg-info/dependency_links.txt
|
|
12
|
+
br_codex_xx.egg-info/entry_points.txt
|
|
13
|
+
br_codex_xx.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
bpp_lang
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=70.1", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "br-codex_xx"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
authors = [{ name = "Thurzingg" }]
|
|
9
|
+
description = "Interpretador da linguagem B++ em portugues"
|
|
10
|
+
readme = "README.md"
|
|
11
|
+
requires-python = ">=3.8"
|
|
12
|
+
|
|
13
|
+
[project.scripts]
|
|
14
|
+
bpp = "bpp_lang.cli:main"
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
import os
|
|
3
|
+
import subprocess
|
|
4
|
+
from setuptools import Command, find_packages, setup
|
|
5
|
+
from setuptools.command.build_py import build_py
|
|
6
|
+
from setuptools.command.bdist_wheel import bdist_wheel
|
|
7
|
+
|
|
8
|
+
ROOT = Path(__file__).parent.resolve()
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class BuildInterpreter(Command):
|
|
12
|
+
description = "compile o interpretador B++"
|
|
13
|
+
user_options = []
|
|
14
|
+
|
|
15
|
+
def initialize_options(self):
|
|
16
|
+
pass
|
|
17
|
+
|
|
18
|
+
def finalize_options(self):
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
def run(self):
|
|
22
|
+
output = Path(self.get_finalized_command("build_py").build_lib) / "bpp_lang" / "bin" / "bpp"
|
|
23
|
+
output.parent.mkdir(parents=True, exist_ok=True)
|
|
24
|
+
compiler = os.environ.get("CXX", "g++")
|
|
25
|
+
subprocess.check_call([
|
|
26
|
+
compiler, "-std=c++17", "-O2", "-Wall", "-Wextra", "-Wpedantic", "-Wconversion",
|
|
27
|
+
str(ROOT / "bpp.cpp"), "-o", str(output),
|
|
28
|
+
])
|
|
29
|
+
if os.name != "nt":
|
|
30
|
+
output.chmod(0o755)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class BuildPyWithInterpreter(build_py):
|
|
34
|
+
def run(self):
|
|
35
|
+
super().run()
|
|
36
|
+
self.run_command("build_interpreter")
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class PlatformWheel(bdist_wheel):
|
|
40
|
+
def finalize_options(self):
|
|
41
|
+
super().finalize_options()
|
|
42
|
+
self.root_is_pure = False
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
setup(
|
|
46
|
+
name="br-codex_xx",
|
|
47
|
+
version="0.1.0",
|
|
48
|
+
author="Thurzingg",
|
|
49
|
+
description="Interpretador da linguagem de programacao B++ em portugues",
|
|
50
|
+
long_description=Path(ROOT / "README.md").read_text(encoding="utf-8"),
|
|
51
|
+
long_description_content_type="text/markdown",
|
|
52
|
+
packages=find_packages(),
|
|
53
|
+
package_data={"bpp_lang": ["bin/bpp"]},
|
|
54
|
+
include_package_data=True,
|
|
55
|
+
cmdclass={
|
|
56
|
+
"build_interpreter": BuildInterpreter,
|
|
57
|
+
"build_py": BuildPyWithInterpreter,
|
|
58
|
+
"bdist_wheel": PlatformWheel,
|
|
59
|
+
},
|
|
60
|
+
entry_points={"console_scripts": ["bpp=bpp_lang.cli:main"]},
|
|
61
|
+
python_requires=">=3.8",
|
|
62
|
+
)
|