Merge pull request #42 from mist-go/init-and-expr-statements
Init and expression statements
This commit is contained in:
@@ -27,3 +27,5 @@ target
|
||||
/target
|
||||
|
||||
**/build
|
||||
|
||||
.mist/
|
||||
|
||||
+2
-2
@@ -25,7 +25,7 @@ cargo_metadata = "0.23.1"
|
||||
|
||||
[[bin]]
|
||||
name = "mist"
|
||||
path = "build/main.rs"
|
||||
path = ".mist/src/main.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "mist-header"
|
||||
@@ -33,4 +33,4 @@ path = "src/_header.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "mist-analyzer"
|
||||
path = "build/analyzer.rs"
|
||||
path = ".mist/src/analyzer.rs"
|
||||
|
||||
@@ -5,6 +5,6 @@ edition = "2024"
|
||||
|
||||
[[bin]]
|
||||
name = "main"
|
||||
path = "build/main.rs"
|
||||
path = ".mist/src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"src": "src",
|
||||
"output": "build"
|
||||
}
|
||||
@@ -15,7 +15,6 @@ pub class Application {
|
||||
|
||||
pub constructor(str* name) {
|
||||
self.name = name.to_string();
|
||||
|
||||
self.tasks = new Vec();
|
||||
self.plugins = new Vec();
|
||||
|
||||
@@ -79,15 +78,15 @@ pub class Application {
|
||||
self.logger.info("shutdown event");
|
||||
}
|
||||
|
||||
event::Event::PluginLoaded(name) => {
|
||||
event::Event::PluginLoaded[name] => {
|
||||
println!("plugin loaded: {}", name);
|
||||
}
|
||||
|
||||
event::Event::TaskExecuted(name) => {
|
||||
event::Event::TaskExecuted[name] => {
|
||||
println!("task executed: {}", name);
|
||||
}
|
||||
|
||||
event::Event::Error(message) => {
|
||||
event::Event::Error[message] => {
|
||||
self.logger.error(&message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,9 +7,6 @@ pub mod event;
|
||||
void main() {
|
||||
var mut app_instance = new app::Application("mist-app");
|
||||
|
||||
// greeting::register(&mut app_instance);
|
||||
// statistics::register(&mut app_instance);
|
||||
|
||||
app_instance.boot();
|
||||
app_instance.run();
|
||||
}
|
||||
+5
-25
@@ -2,34 +2,11 @@ use serde::Serialize;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub enum BinaryOp {
|
||||
Plus,
|
||||
Minus,
|
||||
Multiply,
|
||||
Divide,
|
||||
Modulo,
|
||||
Equal,
|
||||
NotEqual,
|
||||
LessThan,
|
||||
GreaterThan,
|
||||
LessThanOrEqual,
|
||||
GreaterThanOrEqual,
|
||||
And,
|
||||
Or,
|
||||
ShiftLeft,
|
||||
ShiftRight,
|
||||
RangeInclusive,
|
||||
RangeExclusive,
|
||||
BitAnd,
|
||||
BitOr,
|
||||
BitXor,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub enum Expression {
|
||||
Literal(Literal),
|
||||
Path(ExprPath),
|
||||
Statement(Box<Statement>),
|
||||
Fix {
|
||||
initial: Box<Expression>,
|
||||
prefixes: Vec<Prefix>,
|
||||
@@ -37,7 +14,7 @@ pub enum Expression {
|
||||
},
|
||||
Binary {
|
||||
lhs: Box<Expression>,
|
||||
op: BinaryOp,
|
||||
op: String,
|
||||
rhs: Box<Expression>,
|
||||
},
|
||||
}
|
||||
@@ -69,8 +46,11 @@ pub enum Postfix {
|
||||
Call(Vec<Expression>),
|
||||
MacroCall(String),
|
||||
StructCall(Vec<(Identifier, Expression)>),
|
||||
Assign(String, Box<Expression>),
|
||||
Index(Expression),
|
||||
As(TypeExpr),
|
||||
Increment,
|
||||
Decrement,
|
||||
Try,
|
||||
}
|
||||
|
||||
|
||||
@@ -3,19 +3,15 @@ use serde::Serialize;
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Default)]
|
||||
pub struct Block(pub Vec<Spanned<Statement>>);
|
||||
pub struct Block(
|
||||
pub Vec<Spanned<Expression>>,
|
||||
pub Option<Spanned<Expression>>,
|
||||
);
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub enum Statement {
|
||||
Expression(Expression),
|
||||
Block(Block),
|
||||
|
||||
VarDecl(VarDeclStmt),
|
||||
Assign {
|
||||
target: Expression,
|
||||
compound: String,
|
||||
value: Expression,
|
||||
},
|
||||
If {
|
||||
initial: StatementBranch,
|
||||
else_if: Vec<StatementBranch>,
|
||||
@@ -39,9 +35,6 @@ pub enum Statement {
|
||||
Return(Option<Expression>),
|
||||
Break,
|
||||
Continue,
|
||||
|
||||
Increment(Expression),
|
||||
Decrement(Expression),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
|
||||
+74
-103
@@ -29,11 +29,10 @@ keyword = {
|
||||
| "true"
|
||||
| "false"
|
||||
| "dyn"
|
||||
| "self"
|
||||
}
|
||||
|
||||
identifier = @{
|
||||
!keyword ~ (ASCII_ALPHA | "_") ~ (ASCII_ALPHANUMERIC | "_")*
|
||||
!(keyword ~ !(ASCII_ALPHANUMERIC | "_")) ~ (ASCII_ALPHA | "_") ~ (ASCII_ALPHANUMERIC | "_")*
|
||||
}
|
||||
|
||||
integer = @{ ASCII_DIGIT+ }
|
||||
@@ -77,14 +76,6 @@ visibility = { "pub" ~ ("(" ~ static_path ~ ")")? }
|
||||
mutable = { "mut" }
|
||||
var = { "var" }
|
||||
|
||||
// ======================================================
|
||||
// ERROR RECOVERY
|
||||
// ======================================================
|
||||
|
||||
unexpected_statement = {
|
||||
(!(semicolon | "}" | statement) ~ ANY)+
|
||||
}
|
||||
|
||||
// ======================================================
|
||||
// GENERICS
|
||||
// ======================================================
|
||||
@@ -143,11 +134,11 @@ literal = {
|
||||
// ======================================================
|
||||
|
||||
tuple_pattern = {
|
||||
"(" ~ (identifier ~ ("," ~ identifier)*) ~ ")"
|
||||
"[" ~ (identifier ~ ("," ~ identifier)*) ~ "]"
|
||||
}
|
||||
|
||||
named_tuple_pattern = {
|
||||
static_path ~ "(" ~ (identifier ~ ("," ~ identifier)*)? ~ ")"
|
||||
static_path ~ "[" ~ (identifier ~ ("," ~ identifier)*)? ~ "]"
|
||||
}
|
||||
|
||||
struct_pattern = {
|
||||
@@ -339,79 +330,58 @@ top_level = {
|
||||
// ======================================================
|
||||
|
||||
block = {
|
||||
"{" ~ (statement | unexpected_statement)* ~ "}"
|
||||
"{" ~ statement_list ~ expr? ~ "}"
|
||||
}
|
||||
|
||||
statement_list = {
|
||||
statement*
|
||||
}
|
||||
|
||||
statement = _{
|
||||
match_stmt
|
||||
| if_stmt
|
||||
| while_stmt
|
||||
| c_for_stmt
|
||||
| for_stmt
|
||||
| return_stmt
|
||||
| break_stmt
|
||||
| continue_stmt
|
||||
| block
|
||||
| increment_statement
|
||||
| decrement_statement
|
||||
| var_decl_statement
|
||||
| assign_statement
|
||||
| expr_stmt
|
||||
control_flow
|
||||
| (expr ~ semicolon)
|
||||
}
|
||||
|
||||
// ------------------------------------------------------
|
||||
// BASIC STATEMENTS
|
||||
// ------------------------------------------------------
|
||||
|
||||
expr_stmt = {
|
||||
expr ~ semicolon
|
||||
basic_stmt = {
|
||||
return_stmt
|
||||
| break_stmt
|
||||
| continue_stmt
|
||||
| var_decl_statement
|
||||
}
|
||||
|
||||
return_stmt = {
|
||||
"return" ~ expr? ~ semicolon
|
||||
"return" ~ expr?
|
||||
}
|
||||
|
||||
break_stmt = {
|
||||
"break" ~ semicolon
|
||||
"break"
|
||||
}
|
||||
|
||||
continue_stmt = {
|
||||
"continue" ~ semicolon
|
||||
"continue"
|
||||
}
|
||||
|
||||
var_decl_statement = {
|
||||
var_decl ~ ("=" ~ expr)? ~ semicolon
|
||||
}
|
||||
|
||||
increment_statement = {
|
||||
expr ~ "++" ~ semicolon
|
||||
}
|
||||
|
||||
decrement_statement = {
|
||||
expr ~ "--" ~ semicolon
|
||||
}
|
||||
|
||||
compound_assign = {
|
||||
"="
|
||||
| "+="
|
||||
| "-="
|
||||
| "/="
|
||||
| "%="
|
||||
| "&="
|
||||
| "|="
|
||||
| "^="
|
||||
| "<<="
|
||||
| ">>="
|
||||
}
|
||||
|
||||
assign_statement = {
|
||||
expr ~ compound_assign ~ expr ~ semicolon
|
||||
var_decl ~ ("=" ~ expr)?
|
||||
}
|
||||
|
||||
// ------------------------------------------------------
|
||||
// CONDITIONALS
|
||||
// ------------------------------------------------------
|
||||
|
||||
control_flow = {
|
||||
if_stmt
|
||||
| while_stmt
|
||||
| c_for_stmt
|
||||
| for_stmt
|
||||
| match_stmt
|
||||
| block
|
||||
}
|
||||
|
||||
statement_branch = { "(" ~ expr ~ ")" ~ statement }
|
||||
|
||||
else_if = {
|
||||
@@ -478,7 +448,7 @@ array = {
|
||||
// MACROS
|
||||
// ------------------------------------------------------
|
||||
|
||||
macro_inner_v = {
|
||||
macro_inner_v = @{
|
||||
string_lit
|
||||
| ("(" ~ macro_inner_v* ~ ")")
|
||||
| (!("(" | ")") ~ ANY)
|
||||
@@ -497,7 +467,9 @@ expr_path = {
|
||||
}
|
||||
|
||||
primary = {
|
||||
literal
|
||||
control_flow
|
||||
| basic_stmt
|
||||
| literal
|
||||
| expr_path
|
||||
| tuple
|
||||
| array
|
||||
@@ -539,6 +511,14 @@ try_px = {
|
||||
"?"
|
||||
}
|
||||
|
||||
increment = {
|
||||
"++"
|
||||
}
|
||||
|
||||
decrement = {
|
||||
"--"
|
||||
}
|
||||
|
||||
postfix = {
|
||||
field_px
|
||||
| call_px
|
||||
@@ -547,6 +527,8 @@ postfix = {
|
||||
| index_px
|
||||
| as_px
|
||||
| try_px
|
||||
| increment
|
||||
| decrement
|
||||
}
|
||||
|
||||
// ------------------------------------------------------
|
||||
@@ -570,51 +552,40 @@ prefix = {
|
||||
}
|
||||
|
||||
// ------------------------------------------------------
|
||||
// OPERATORS (Arranged carefully for PEG priority matching)
|
||||
// OPERATORS
|
||||
// ------------------------------------------------------
|
||||
|
||||
shl = { "<<" }
|
||||
shr = { ">>" }
|
||||
range_inc = { "..=" }
|
||||
range_exc = { ".." }
|
||||
lte = { "<=" }
|
||||
gte = { ">=" }
|
||||
eq = { "==" }
|
||||
neq = { "!=" }
|
||||
and = { "&&" }
|
||||
or = { "||" }
|
||||
add = { "+" }
|
||||
sub = { "-" }
|
||||
mul = { "*" }
|
||||
div = { "/" }
|
||||
rem = { "%" }
|
||||
lt = { "<" }
|
||||
gt = { ">" }
|
||||
bitand = { "&" }
|
||||
bitor = { "|" }
|
||||
bitxor = { "^" }
|
||||
|
||||
bin_op = _{
|
||||
shl
|
||||
| shr
|
||||
| range_inc
|
||||
| range_exc
|
||||
| lte
|
||||
| gte
|
||||
| eq
|
||||
| neq
|
||||
| and
|
||||
| or
|
||||
| lt
|
||||
| gt
|
||||
| add
|
||||
| sub
|
||||
| mul
|
||||
| div
|
||||
| rem
|
||||
| bitand
|
||||
| bitor
|
||||
| bitxor
|
||||
bin_op = {
|
||||
"+="
|
||||
| "-="
|
||||
| "/="
|
||||
| "%="
|
||||
| "&="
|
||||
| "|="
|
||||
| "^="
|
||||
| "<<="
|
||||
| ">>="
|
||||
| "<<"
|
||||
| ">>"
|
||||
| "..="
|
||||
| ".."
|
||||
| "<="
|
||||
| ">="
|
||||
| "=="
|
||||
| "!="
|
||||
| "&&"
|
||||
| "||"
|
||||
| "+"
|
||||
| "-"
|
||||
| "*"
|
||||
| "/"
|
||||
| "%"
|
||||
| "<"
|
||||
| ">"
|
||||
| "&"
|
||||
| "|"
|
||||
| "^"
|
||||
| "="
|
||||
}
|
||||
|
||||
// ------------------------------------------------------
|
||||
|
||||
@@ -18,57 +18,18 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Expression {
|
||||
Rule::expr => {
|
||||
static PRATT_PARSER: OnceLock<PrattParser<Rule>> = OnceLock::new();
|
||||
let pratt = PRATT_PARSER.get_or_init(|| {
|
||||
use Rule::*;
|
||||
use pest::pratt_parser::{Assoc::*, Op};
|
||||
|
||||
PrattParser::new()
|
||||
.op(Op::infix(range_inc, Left) | Op::infix(range_exc, Left))
|
||||
.op(Op::infix(or, Left))
|
||||
.op(Op::infix(and, Left))
|
||||
.op(Op::infix(bitor, Left))
|
||||
.op(Op::infix(bitxor, Left))
|
||||
.op(Op::infix(bitand, Left))
|
||||
.op(Op::infix(eq, Left) | Op::infix(neq, Left))
|
||||
.op(Op::infix(lt, Left)
|
||||
| Op::infix(lte, Left)
|
||||
| Op::infix(gt, Left)
|
||||
| Op::infix(gte, Left))
|
||||
.op(Op::infix(shl, Left) | Op::infix(shr, Left))
|
||||
.op(Op::infix(add, Left) | Op::infix(sub, Left))
|
||||
.op(Op::infix(mul, Left) | Op::infix(div, Left) | Op::infix(rem, Left))
|
||||
PrattParser::new().op(Op::infix(Rule::bin_op, Left))
|
||||
});
|
||||
|
||||
pratt
|
||||
.map_primary(|primary_pair| Expression::try_from(primary_pair))
|
||||
.map_infix(|lhs, op, rhs| {
|
||||
let bin_op = match op.as_rule() {
|
||||
Rule::shl => BinaryOp::ShiftLeft,
|
||||
Rule::shr => BinaryOp::ShiftRight,
|
||||
Rule::range_inc => BinaryOp::RangeInclusive,
|
||||
Rule::range_exc => BinaryOp::RangeExclusive,
|
||||
Rule::lte => BinaryOp::LessThanOrEqual,
|
||||
Rule::gte => BinaryOp::GreaterThanOrEqual,
|
||||
Rule::eq => BinaryOp::Equal,
|
||||
Rule::neq => BinaryOp::NotEqual,
|
||||
Rule::and => BinaryOp::And,
|
||||
Rule::or => BinaryOp::Or,
|
||||
Rule::add => BinaryOp::Plus,
|
||||
Rule::sub => BinaryOp::Minus,
|
||||
Rule::mul => BinaryOp::Multiply,
|
||||
Rule::div => BinaryOp::Divide,
|
||||
Rule::rem => BinaryOp::Modulo,
|
||||
Rule::lt => BinaryOp::LessThan,
|
||||
Rule::gt => BinaryOp::GreaterThan,
|
||||
Rule::bitand => BinaryOp::BitAnd,
|
||||
Rule::bitor => BinaryOp::BitOr,
|
||||
Rule::bitxor => BinaryOp::BitXor,
|
||||
_ => return AstError::bug_unimplemented(op),
|
||||
};
|
||||
|
||||
.map_infix(|expr, op, rhs| {
|
||||
ast_expr!(Expression::Binary {
|
||||
lhs: lhs.map(Box::new),
|
||||
op: Ok(bin_op) as AstResult<'_, BinaryOp>,
|
||||
rhs: rhs.map(Box::new),
|
||||
lhs: expr.map(Box::new).get_map(Box::new),
|
||||
op: Ok(op.as_str().to_string()) as AstResult<'_, String>,
|
||||
rhs: rhs.map(Box::new).get_map(Box::new),
|
||||
})
|
||||
})
|
||||
.parse(inner)
|
||||
@@ -117,6 +78,9 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Expression {
|
||||
Rule::static_path => ast_expr!(Expression::Path(pair.try_into())),
|
||||
Rule::literal => ast_expr!(Expression::Literal(pair.try_into())),
|
||||
Rule::expr_path => ast_expr!(Expression::Path(pair.try_into())),
|
||||
Rule::statement | Rule::basic_stmt | Rule::control_flow => ast_expr!(
|
||||
Expression::Statement(pair.try_into().get_map(Box::new).map(Box::new))
|
||||
),
|
||||
|
||||
_ => AstError::bug_unimplemented(pair),
|
||||
}
|
||||
@@ -185,6 +149,9 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Postfix {
|
||||
|
||||
Rule::try_px => Ok(Postfix::Try),
|
||||
|
||||
Rule::increment => Ok(Postfix::Increment),
|
||||
Rule::decrement => Ok(Postfix::Decrement),
|
||||
|
||||
_ => AstError::bug_unimplemented(pair),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::{
|
||||
Rule,
|
||||
ast::*,
|
||||
ast_ensure, ast_expr,
|
||||
error::{AstError, AstResult, ErrorCode, IntoErr, collect_recovered},
|
||||
error::{AstError, AstResult, IntoErr, collect_recovered},
|
||||
parser::listen_rule,
|
||||
};
|
||||
|
||||
@@ -10,8 +10,10 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Block {
|
||||
type Error = AstError<'a, Self>;
|
||||
|
||||
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
|
||||
let mut inner = pair.clone().into_inner();
|
||||
|
||||
ast_ensure!(pair, Rule::block => {
|
||||
ast_expr!(Block(collect_recovered(pair.into_inner())))
|
||||
ast_expr!(Block(collect_recovered(inner.next().unwrap().into_inner()), inner.next().map(Spanned::try_from).transpose()))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -39,10 +41,8 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Statement {
|
||||
let mut inner = pair.clone().into_inner();
|
||||
|
||||
match rule {
|
||||
Rule::statement => Statement::try_from(inner.next().unwrap()),
|
||||
|
||||
Rule::expr_stmt => {
|
||||
ast_expr!(Statement::Expression(inner.next().unwrap().try_into()))
|
||||
Rule::statement | Rule::basic_stmt | Rule::control_flow => {
|
||||
Statement::try_from(inner.next().unwrap())
|
||||
}
|
||||
|
||||
Rule::block => ast_expr!(Statement::Block(pair.try_into())),
|
||||
@@ -88,12 +88,6 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Statement {
|
||||
body: inner.next().unwrap().try_into().map(Box::new),
|
||||
}),
|
||||
|
||||
Rule::assign_statement => ast_expr!(Statement::Assign {
|
||||
target: inner.next().unwrap().try_into(),
|
||||
compound: Ok(inner.next().unwrap().as_str().trim().to_string())
|
||||
as AstResult<'_, String>,
|
||||
value: inner.next().unwrap().try_into(),
|
||||
}),
|
||||
Rule::match_stmt => ast_expr!(Statement::Match(
|
||||
inner.next().unwrap().try_into(),
|
||||
inner
|
||||
@@ -107,23 +101,6 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Statement {
|
||||
.collect::<AstResult<'a, Vec<_>>>(),
|
||||
)),
|
||||
|
||||
Rule::increment_statement => {
|
||||
ast_expr!(Statement::Increment(inner.next().unwrap().try_into()))
|
||||
}
|
||||
|
||||
Rule::decrement_statement => {
|
||||
ast_expr!(Statement::Decrement(inner.next().unwrap().try_into()))
|
||||
}
|
||||
|
||||
Rule::unexpected_statement => {
|
||||
return Err(AstError {
|
||||
span: pair.as_span(),
|
||||
error_code: ErrorCode::InvalidStatement,
|
||||
error_message: "Invalid Statement".to_string(),
|
||||
recovered: None,
|
||||
});
|
||||
}
|
||||
|
||||
_ => AstError::bug_unimplemented(pair),
|
||||
}
|
||||
}
|
||||
|
||||
+2
-4
@@ -8,8 +8,6 @@ use std::{
|
||||
use cargo_metadata::{CompilerMessage, Message};
|
||||
use mist_parser::rev_mapper::{RustMap, find_mapping, get_mapping};
|
||||
|
||||
use crate::transpiler::Config;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MistDiagnosticMessage {
|
||||
pub message: String,
|
||||
@@ -26,7 +24,7 @@ pub enum MistDiagnostic {
|
||||
Rust(CompilerMessage),
|
||||
}
|
||||
|
||||
pub fn build(mut args: Vec<String>, config: Config, root: PathBuf) -> bool {
|
||||
pub fn build(mut args: Vec<String>, root: PathBuf) -> bool {
|
||||
args.remove(0);
|
||||
args.insert(1, "--message-format=json".to_string());
|
||||
|
||||
@@ -55,7 +53,7 @@ pub fn build(mut args: Vec<String>, config: Config, root: PathBuf) -> bool {
|
||||
|
||||
let mist_file = span
|
||||
.file_name
|
||||
.replacen(&config.output, &config.src, 1)
|
||||
.replacen(".mist/src", "src", 1)
|
||||
.replace(".rs", ".mist");
|
||||
|
||||
let mist_path = root.join(&mist_file);
|
||||
|
||||
+24
-52
@@ -1,8 +1,8 @@
|
||||
use mist_parser::ast::{
|
||||
Attribute, BinaryOp, Block, ClassItem, EnumItem, ExprPath, ExprPathSegment, Expression,
|
||||
FieldDecl, FunctionDecl, Generic, GenericDecl, Generics, GenericsDecl, Identifier, ImplDecl,
|
||||
Literal, Path, Pattern, Postfix, Prefix, Spanned, Statement, StatementBranch, TopLevel,
|
||||
TopLevelKind, TypeExpr, TypeExprKind, TypePostfix, VarDecl, VarDeclStmt, Visibility,
|
||||
Attribute, Block, ClassItem, EnumItem, ExprPath, ExprPathSegment, Expression, FieldDecl,
|
||||
FunctionDecl, Generic, GenericDecl, Generics, GenericsDecl, Identifier, ImplDecl, Literal,
|
||||
Path, Pattern, Postfix, Prefix, Spanned, Statement, StatementBranch, TopLevel, TopLevelKind,
|
||||
TypeExpr, TypeExprKind, TypePostfix, VarDecl, VarDeclStmt, Visibility,
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -169,6 +169,12 @@ impl GetRust for Expression {
|
||||
match self {
|
||||
Expression::Path(path) => path.get_rust(),
|
||||
Expression::Literal(literal) => literal.get_rust(),
|
||||
Expression::Statement(stmt) => {
|
||||
let mut cg = RustCodegen::new();
|
||||
cg.indent += 1;
|
||||
stmt.to_rust(&mut cg);
|
||||
cg.output
|
||||
}
|
||||
Expression::Fix {
|
||||
initial,
|
||||
prefixes,
|
||||
@@ -181,29 +187,7 @@ impl GetRust for Expression {
|
||||
}
|
||||
// Safely integrated to handle the tree structure built by the Pratt Parser
|
||||
Expression::Binary { lhs, op, rhs } => {
|
||||
let op_str = match op {
|
||||
BinaryOp::Plus => "+",
|
||||
BinaryOp::Minus => "-",
|
||||
BinaryOp::Multiply => "*",
|
||||
BinaryOp::Divide => "/",
|
||||
BinaryOp::Modulo => "%",
|
||||
BinaryOp::Equal => "==",
|
||||
BinaryOp::NotEqual => "!=",
|
||||
BinaryOp::LessThan => "<",
|
||||
BinaryOp::GreaterThan => ">",
|
||||
BinaryOp::LessThanOrEqual => "<=",
|
||||
BinaryOp::GreaterThanOrEqual => ">=",
|
||||
BinaryOp::And => "&&",
|
||||
BinaryOp::Or => "||",
|
||||
BinaryOp::ShiftLeft => "<<",
|
||||
BinaryOp::ShiftRight => ">>",
|
||||
BinaryOp::RangeInclusive => "..=",
|
||||
BinaryOp::RangeExclusive => "..",
|
||||
BinaryOp::BitAnd => "&",
|
||||
BinaryOp::BitOr => "|",
|
||||
BinaryOp::BitXor => "^",
|
||||
};
|
||||
format!("{} {} {}", lhs.get_rust(), op_str, rhs.get_rust())
|
||||
format!("{} {} {}", lhs.get_rust(), op, rhs.get_rust())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -313,6 +297,10 @@ impl GetRust for Postfix {
|
||||
Postfix::As(ty) => format!(" as {}", ty.get_rust()),
|
||||
|
||||
Postfix::Try => String::from("?"),
|
||||
|
||||
Postfix::Assign(cmp, expr) => format!("{cmp} {}", expr.get_rust()),
|
||||
Postfix::Increment => "+=1".to_string(),
|
||||
Postfix::Decrement => "-=1".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -336,7 +324,11 @@ impl<T: ToRust> ToRust for Spanned<T> {
|
||||
impl ToRust for Block {
|
||||
fn to_rust(self, cg: &mut RustCodegen) {
|
||||
for stmt in self.0 {
|
||||
stmt.to_rust(cg);
|
||||
cg.add_indentedln(&(stmt.get_rust() + ";"));
|
||||
}
|
||||
|
||||
if let Some(soft_return) = self.1 {
|
||||
cg.add_indentedln(&soft_return.get_rust());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -608,10 +600,6 @@ impl ToRust for TopLevelKind {
|
||||
impl ToRust for Statement {
|
||||
fn to_rust(self, cg: &mut RustCodegen) {
|
||||
match self {
|
||||
Statement::Expression(expr) => {
|
||||
cg.add_indentedln(&format!("{};", expr.get_rust()));
|
||||
}
|
||||
|
||||
Statement::Block(block) => {
|
||||
cg.add_indentedln("{");
|
||||
cg.indent += 1;
|
||||
@@ -625,20 +613,7 @@ impl ToRust for Statement {
|
||||
.map(|e| format!(" = {}", e.get_rust()))
|
||||
.unwrap_or_default();
|
||||
|
||||
cg.add_indentedln(&format!("let {}{};", decl.get_rust(), init));
|
||||
}
|
||||
|
||||
Statement::Assign {
|
||||
target,
|
||||
compound,
|
||||
value,
|
||||
} => {
|
||||
cg.add_indentedln(&format!(
|
||||
"{} {} {};",
|
||||
target.get_rust(),
|
||||
compound,
|
||||
value.get_rust(),
|
||||
));
|
||||
cg.add_indentedln(&format!("let {}{}", decl.get_rust(), init));
|
||||
}
|
||||
|
||||
Statement::Match(expr, match_items) => {
|
||||
@@ -733,14 +708,11 @@ impl ToRust for Statement {
|
||||
|
||||
Statement::Return(expr) => {
|
||||
let val = expr.map(|e| e.get_rust()).unwrap_or_default();
|
||||
cg.add_indentedln(&format!("return {};", val));
|
||||
cg.add_indentedln(&format!("return {}", val));
|
||||
}
|
||||
|
||||
Statement::Break => cg.add_indentedln("break;"),
|
||||
Statement::Continue => cg.add_indentedln("continue;"),
|
||||
|
||||
Statement::Increment(e) => cg.add_indentedln(&format!("{}+=1;", e.get_rust())),
|
||||
Statement::Decrement(e) => cg.add_indentedln(&format!("{}-=1;", e.get_rust())),
|
||||
Statement::Break => cg.add_indentedln("break"),
|
||||
Statement::Continue => cg.add_indentedln("continue"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+52
-2
@@ -1,5 +1,6 @@
|
||||
use <std::process>;
|
||||
use <std::env>;
|
||||
use <std::fs>;
|
||||
|
||||
pub mod builder;
|
||||
pub mod codegen;
|
||||
@@ -15,9 +16,12 @@ void main() {
|
||||
|
||||
match (args[1].as_str()) {
|
||||
"run" | "build" | "check" | "r" | "b" | "c" => {
|
||||
var (config, root) = transpiler::build();
|
||||
|
||||
var root = transpiler::build();
|
||||
|
||||
println!("");
|
||||
if (builder::build(args, config, root)) {
|
||||
|
||||
if (builder::build(args, root)) {
|
||||
println!("\x1b[32m\nBuild successful\x1b[0m");
|
||||
} else {
|
||||
println!("\x1b[31m\nBuild failed\x1b[0m");
|
||||
@@ -26,6 +30,9 @@ void main() {
|
||||
"transpile" | "t" => {
|
||||
transpiler::build();
|
||||
}
|
||||
"init" => {
|
||||
init_project(args);
|
||||
}
|
||||
"version" | "--version" | "-v" => {
|
||||
println!("mist {}", env!("CARGO_PKG_VERSION"));
|
||||
}
|
||||
@@ -55,6 +62,49 @@ void print_usage() {
|
||||
println!(
|
||||
" \x1b[36m mist check\x1b[0m,\x1b[36m c\x1b[0m check the project in the current directory\n"
|
||||
);
|
||||
println!(
|
||||
" \x1b[36m mist init\x1b[0m initialize a project in the current folder\n"
|
||||
);
|
||||
println!(" \x1b[36m mist version \x1b[0m print the compiler version\n");
|
||||
println!(" \x1b[36m mist help\x1b[0m print this message\n");
|
||||
}
|
||||
|
||||
void init_project(Vec<String> mut args) {
|
||||
args.remove(0);
|
||||
|
||||
new process::Command("cargo")
|
||||
.args(args)
|
||||
.stdout(process::Stdio::inherit())
|
||||
.stderr(process::Stdio::inherit())
|
||||
.stdin(process::Stdio::inherit())
|
||||
.spawn()
|
||||
.expect("Failed to run cargo").wait().expect("Unable to wait");
|
||||
|
||||
bool is_lib = fs::metadata("src/lib.rs").is_ok();
|
||||
|
||||
if (is_lib) {
|
||||
fs::remove_file("src/lib.rs").expect("Failed to remove src/lib.rs");
|
||||
fs::write("src/lib.mist", "void test() {\n}").expect("Failed to create src/lib.mist");
|
||||
} else {
|
||||
fs::remove_file("src/main.rs").expect("Failed to remove src/main.rs");
|
||||
fs::write("src/main.mist", "void main() {\n println!(\"Hello, World!\");\n}\n").expect("Failed to create src/main.mist");
|
||||
}
|
||||
|
||||
inject_mist_target(is_lib);
|
||||
|
||||
println!("\n\x1b[34minfo\x1b[0m: Please open Cargo.toml and adjust `\x1b[35mname\x1b[0m = ` as needed, Thank you for using Mist!\n");
|
||||
}
|
||||
|
||||
void inject_mist_target(bool is_lib) {
|
||||
String toml_content = fs::read_to_string("Cargo.toml").expect("Failed to read Cargo.toml");
|
||||
|
||||
str* inject;
|
||||
|
||||
if (is_lib) {
|
||||
inject = "\n[lib]\nname = \"my_lib\"\npath = \".mist/src/lib.rs\"\n";
|
||||
} else {
|
||||
inject = "\n[[bin]]\nname = \"my_bin\"\npath = \".mist/src/main.rs\"\n";
|
||||
}
|
||||
|
||||
fs::write("Cargo.toml", toml_content+inject).expect("Failed to create src/main.mist");
|
||||
}
|
||||
|
||||
+7
-36
@@ -6,25 +6,16 @@ use std::{
|
||||
};
|
||||
|
||||
use mist_parser::error::ParseError;
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Config {
|
||||
pub src: String,
|
||||
pub output: String,
|
||||
}
|
||||
|
||||
pub fn build() -> (Config, PathBuf) {
|
||||
pub fn build() -> PathBuf {
|
||||
let start = Instant::now();
|
||||
|
||||
let root = find_project_root().unwrap_or_else(|| {
|
||||
panic!("error: could not find project root (mist.json)");
|
||||
});
|
||||
let root = std::env::current_dir()
|
||||
.ok()
|
||||
.expect("Unable to find project root");
|
||||
|
||||
let config = load_config(&root);
|
||||
|
||||
let src_dir = root.join(&config.src);
|
||||
let out_dir = root.join(&config.output);
|
||||
let src_dir = root.join("src");
|
||||
let out_dir = root.join(".mist/src");
|
||||
|
||||
build_dir(&root, &src_dir, &src_dir, &out_dir);
|
||||
|
||||
@@ -35,7 +26,7 @@ pub fn build() -> (Config, PathBuf) {
|
||||
elapsed
|
||||
);
|
||||
|
||||
(config, root)
|
||||
root
|
||||
}
|
||||
|
||||
fn build_dir(root: &Path, base_src: &Path, current_dir: &Path, out_dir: &Path) {
|
||||
@@ -173,23 +164,3 @@ fn should_skip(source: &Path, output: &Path) -> bool {
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
pub fn find_project_root() -> Option<PathBuf> {
|
||||
let mut dir = std::env::current_dir().ok()?;
|
||||
|
||||
loop {
|
||||
if dir.join("mist.json").exists() {
|
||||
return Some(dir);
|
||||
}
|
||||
|
||||
if !dir.pop() {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn load_config(root: &Path) -> Config {
|
||||
let content = fs::read_to_string(root.join("mist.json")).expect("failed to read mist.json");
|
||||
|
||||
serde_json::from_str(&content).expect("invalid mist.json format")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user