Este projeto tem como objetivo implementar uma versão de portugol semelhante ao JavaScript.
Para executar o interpretador, você precisa ter PHP 8.2 ou superior instalado no seu sistema, e também o Composer.
Para instalar as dependências (nenhuma até agora), execute:
composer install
Para executar o interpretador, rode:
./phortugol <filename>
ou simplesmente execute o interpretador sem nenhum argumento para entrar no modo REPL:
./phortugol
Para rodar os testes (boa parte do parser e scanner estão cobertos com testes) basta rodar
composer test
.port
Ainda não está totalmente finalizada, e talvez no futuro eu migre pra uma notação EBNF. A tendência é as regras com precedência mais alta ficarem mais no fundo do arquivo. Começamos com statements, e depois vamos pra expressions.
program -> declaration* EOF;
// stmts
declaration -> funcDecl | varDecl | statement;
funcDecl -> ("função" | "funcao" ) function;
function -> IDENTIFIER "(" parameters? ")" block;
parameters -> IDENTIFIER ( "," IDENTIFIER)*;
varDecl -> "var" IDENTIFIER ("=" expression)? ";"
statement -> exprStmt
| printStmt
| block
| ifStmt
| whileStmt
| forStmt
| returnStmt
exprStmt -> expression ";" ;
printStmt -> "escreva" expression ";" ;
block -> "{" declaration* "}";
ifStmt -> "se" "(" expression ")" statement ("senao" statement)? ;
whileStmt -> "enquanto" "(" expression ")" statement;
forStmt -> "repetir" "("
(varDecl | exprStmt)? ";"
expression? ";"
expression? ")" statement;
returnStmt -> "retorne" expression? ";" ;
// Expressions
expression → lambda ;
lambda -> "(" parameters? ")" "=>" (block | expression)
| assignment;
assignment -> IDENTIFIER "=" assignment
| conditional;
conditional -> logic_or ("?" expression ":" conditional)?;
logic_or → logic_and ( "OU" logic_and )* ;
logic_and → equality ( "E" equality )* ;
equality → comparison ( ( "!=" | "==" ) comparison )* ;
comparison → term ( ( ">" | ">=" | "<" | "<=" ) term )* ;
term → factor ( ( "-" | "+" ) factor )* ;
factor → unary ( ( "/" | "*" | "%" ) unary )* ;
unary → ( "!" | "-" ) unary
| call ;
call -> arrayGet ( "(" arguments? ")" )*;
arrayGet -> arrayDef ( "[" (expression) "]" )*
arrayDef -> "[" (expression)? ("," expression)* "]";
| primary;
primary → NUMBER | STRING | "verdadeiro" | "falso" | "nulo" | "NL"
| "(" expression ")" ;
arguments -> expression ("," expression)*;