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.
@@ -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,4 @@
1
+ include bpp.cpp
2
+ include README.md
3
+ include LICENSE
4
+ recursive-include bpp_lang *.py
@@ -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,3 @@
1
+ """Ferramentas de execucao da linguagem B++."""
2
+
3
+ __version__ = "0.1.0"
@@ -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,2 @@
1
+ [console_scripts]
2
+ bpp = bpp_lang.cli:main
@@ -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,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -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
+ )