Merge pull request #42 from mist-go/init-and-expr-statements

Init and expression statements
This commit is contained in:
2026-05-21 11:16:48 +02:00
committed by GitHub
15 changed files with 193 additions and 320 deletions
+2
View File
@@ -27,3 +27,5 @@ target
/target /target
**/build **/build
.mist/
+2 -2
View File
@@ -25,7 +25,7 @@ cargo_metadata = "0.23.1"
[[bin]] [[bin]]
name = "mist" name = "mist"
path = "build/main.rs" path = ".mist/src/main.rs"
[[bin]] [[bin]]
name = "mist-header" name = "mist-header"
@@ -33,4 +33,4 @@ path = "src/_header.rs"
[[bin]] [[bin]]
name = "mist-analyzer" name = "mist-analyzer"
path = "build/analyzer.rs" path = ".mist/src/analyzer.rs"
+1 -1
View File
@@ -5,6 +5,6 @@ edition = "2024"
[[bin]] [[bin]]
name = "main" name = "main"
path = "build/main.rs" path = ".mist/src/main.rs"
[dependencies] [dependencies]
-4
View File
@@ -1,4 +0,0 @@
{
"src": "src",
"output": "build"
}
+3 -4
View File
@@ -15,7 +15,6 @@ pub class Application {
pub constructor(str* name) { pub constructor(str* name) {
self.name = name.to_string(); self.name = name.to_string();
self.tasks = new Vec(); self.tasks = new Vec();
self.plugins = new Vec(); self.plugins = new Vec();
@@ -79,15 +78,15 @@ pub class Application {
self.logger.info("shutdown event"); self.logger.info("shutdown event");
} }
event::Event::PluginLoaded(name) => { event::Event::PluginLoaded[name] => {
println!("plugin loaded: {}", name); println!("plugin loaded: {}", name);
} }
event::Event::TaskExecuted(name) => { event::Event::TaskExecuted[name] => {
println!("task executed: {}", name); println!("task executed: {}", name);
} }
event::Event::Error(message) => { event::Event::Error[message] => {
self.logger.error(&message); self.logger.error(&message);
} }
} }
-3
View File
@@ -7,9 +7,6 @@ pub mod event;
void main() { void main() {
var mut app_instance = new app::Application("mist-app"); var mut app_instance = new app::Application("mist-app");
// greeting::register(&mut app_instance);
// statistics::register(&mut app_instance);
app_instance.boot(); app_instance.boot();
app_instance.run(); app_instance.run();
} }
+5 -25
View File
@@ -2,34 +2,11 @@ use serde::Serialize;
use super::*; 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)] #[derive(Debug, Clone, Serialize)]
pub enum Expression { pub enum Expression {
Literal(Literal), Literal(Literal),
Path(ExprPath), Path(ExprPath),
Statement(Box<Statement>),
Fix { Fix {
initial: Box<Expression>, initial: Box<Expression>,
prefixes: Vec<Prefix>, prefixes: Vec<Prefix>,
@@ -37,7 +14,7 @@ pub enum Expression {
}, },
Binary { Binary {
lhs: Box<Expression>, lhs: Box<Expression>,
op: BinaryOp, op: String,
rhs: Box<Expression>, rhs: Box<Expression>,
}, },
} }
@@ -69,8 +46,11 @@ pub enum Postfix {
Call(Vec<Expression>), Call(Vec<Expression>),
MacroCall(String), MacroCall(String),
StructCall(Vec<(Identifier, Expression)>), StructCall(Vec<(Identifier, Expression)>),
Assign(String, Box<Expression>),
Index(Expression), Index(Expression),
As(TypeExpr), As(TypeExpr),
Increment,
Decrement,
Try, Try,
} }
+4 -11
View File
@@ -3,19 +3,15 @@ use serde::Serialize;
use super::*; use super::*;
#[derive(Debug, Clone, Serialize, Default)] #[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)] #[derive(Debug, Clone, Serialize)]
pub enum Statement { pub enum Statement {
Expression(Expression),
Block(Block), Block(Block),
VarDecl(VarDeclStmt), VarDecl(VarDeclStmt),
Assign {
target: Expression,
compound: String,
value: Expression,
},
If { If {
initial: StatementBranch, initial: StatementBranch,
else_if: Vec<StatementBranch>, else_if: Vec<StatementBranch>,
@@ -39,9 +35,6 @@ pub enum Statement {
Return(Option<Expression>), Return(Option<Expression>),
Break, Break,
Continue, Continue,
Increment(Expression),
Decrement(Expression),
} }
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
+74 -103
View File
@@ -29,11 +29,10 @@ keyword = {
| "true" | "true"
| "false" | "false"
| "dyn" | "dyn"
| "self"
} }
identifier = @{ identifier = @{
!keyword ~ (ASCII_ALPHA | "_") ~ (ASCII_ALPHANUMERIC | "_")* !(keyword ~ !(ASCII_ALPHANUMERIC | "_")) ~ (ASCII_ALPHA | "_") ~ (ASCII_ALPHANUMERIC | "_")*
} }
integer = @{ ASCII_DIGIT+ } integer = @{ ASCII_DIGIT+ }
@@ -77,14 +76,6 @@ visibility = { "pub" ~ ("(" ~ static_path ~ ")")? }
mutable = { "mut" } mutable = { "mut" }
var = { "var" } var = { "var" }
// ======================================================
// ERROR RECOVERY
// ======================================================
unexpected_statement = {
(!(semicolon | "}" | statement) ~ ANY)+
}
// ====================================================== // ======================================================
// GENERICS // GENERICS
// ====================================================== // ======================================================
@@ -143,11 +134,11 @@ literal = {
// ====================================================== // ======================================================
tuple_pattern = { tuple_pattern = {
"(" ~ (identifier ~ ("," ~ identifier)*) ~ ")" "[" ~ (identifier ~ ("," ~ identifier)*) ~ "]"
} }
named_tuple_pattern = { named_tuple_pattern = {
static_path ~ "(" ~ (identifier ~ ("," ~ identifier)*)? ~ ")" static_path ~ "[" ~ (identifier ~ ("," ~ identifier)*)? ~ "]"
} }
struct_pattern = { struct_pattern = {
@@ -339,79 +330,58 @@ top_level = {
// ====================================================== // ======================================================
block = { block = {
"{" ~ (statement | unexpected_statement)* ~ "}" "{" ~ statement_list ~ expr? ~ "}"
}
statement_list = {
statement*
} }
statement = _{ statement = _{
match_stmt control_flow
| if_stmt | (expr ~ semicolon)
| 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
} }
// ------------------------------------------------------ // ------------------------------------------------------
// BASIC STATEMENTS // BASIC STATEMENTS
// ------------------------------------------------------ // ------------------------------------------------------
expr_stmt = { basic_stmt = {
expr ~ semicolon return_stmt
| break_stmt
| continue_stmt
| var_decl_statement
} }
return_stmt = { return_stmt = {
"return" ~ expr? ~ semicolon "return" ~ expr?
} }
break_stmt = { break_stmt = {
"break" ~ semicolon "break"
} }
continue_stmt = { continue_stmt = {
"continue" ~ semicolon "continue"
} }
var_decl_statement = { var_decl_statement = {
var_decl ~ ("=" ~ expr)? ~ semicolon var_decl ~ ("=" ~ expr)?
}
increment_statement = {
expr ~ "++" ~ semicolon
}
decrement_statement = {
expr ~ "--" ~ semicolon
}
compound_assign = {
"="
| "+="
| "-="
| "/="
| "%="
| "&="
| "|="
| "^="
| "<<="
| ">>="
}
assign_statement = {
expr ~ compound_assign ~ expr ~ semicolon
} }
// ------------------------------------------------------ // ------------------------------------------------------
// CONDITIONALS // CONDITIONALS
// ------------------------------------------------------ // ------------------------------------------------------
control_flow = {
if_stmt
| while_stmt
| c_for_stmt
| for_stmt
| match_stmt
| block
}
statement_branch = { "(" ~ expr ~ ")" ~ statement } statement_branch = { "(" ~ expr ~ ")" ~ statement }
else_if = { else_if = {
@@ -478,7 +448,7 @@ array = {
// MACROS // MACROS
// ------------------------------------------------------ // ------------------------------------------------------
macro_inner_v = { macro_inner_v = @{
string_lit string_lit
| ("(" ~ macro_inner_v* ~ ")") | ("(" ~ macro_inner_v* ~ ")")
| (!("(" | ")") ~ ANY) | (!("(" | ")") ~ ANY)
@@ -497,7 +467,9 @@ expr_path = {
} }
primary = { primary = {
literal control_flow
| basic_stmt
| literal
| expr_path | expr_path
| tuple | tuple
| array | array
@@ -539,6 +511,14 @@ try_px = {
"?" "?"
} }
increment = {
"++"
}
decrement = {
"--"
}
postfix = { postfix = {
field_px field_px
| call_px | call_px
@@ -547,6 +527,8 @@ postfix = {
| index_px | index_px
| as_px | as_px
| try_px | try_px
| increment
| decrement
} }
// ------------------------------------------------------ // ------------------------------------------------------
@@ -570,51 +552,40 @@ prefix = {
} }
// ------------------------------------------------------ // ------------------------------------------------------
// OPERATORS (Arranged carefully for PEG priority matching) // OPERATORS
// ------------------------------------------------------ // ------------------------------------------------------
shl = { "<<" } bin_op = {
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
} }
// ------------------------------------------------------ // ------------------------------------------------------
+11 -44
View File
@@ -18,57 +18,18 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Expression {
Rule::expr => { Rule::expr => {
static PRATT_PARSER: OnceLock<PrattParser<Rule>> = OnceLock::new(); static PRATT_PARSER: OnceLock<PrattParser<Rule>> = OnceLock::new();
let pratt = PRATT_PARSER.get_or_init(|| { let pratt = PRATT_PARSER.get_or_init(|| {
use Rule::*;
use pest::pratt_parser::{Assoc::*, Op}; use pest::pratt_parser::{Assoc::*, Op};
PrattParser::new() PrattParser::new().op(Op::infix(Rule::bin_op, Left))
.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))
}); });
pratt pratt
.map_primary(|primary_pair| Expression::try_from(primary_pair)) .map_primary(|primary_pair| Expression::try_from(primary_pair))
.map_infix(|lhs, op, rhs| { .map_infix(|expr, 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),
};
ast_expr!(Expression::Binary { ast_expr!(Expression::Binary {
lhs: lhs.map(Box::new), lhs: expr.map(Box::new).get_map(Box::new),
op: Ok(bin_op) as AstResult<'_, BinaryOp>, op: Ok(op.as_str().to_string()) as AstResult<'_, String>,
rhs: rhs.map(Box::new), rhs: rhs.map(Box::new).get_map(Box::new),
}) })
}) })
.parse(inner) .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::static_path => ast_expr!(Expression::Path(pair.try_into())),
Rule::literal => ast_expr!(Expression::Literal(pair.try_into())), Rule::literal => ast_expr!(Expression::Literal(pair.try_into())),
Rule::expr_path => ast_expr!(Expression::Path(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), _ => 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::try_px => Ok(Postfix::Try),
Rule::increment => Ok(Postfix::Increment),
Rule::decrement => Ok(Postfix::Decrement),
_ => AstError::bug_unimplemented(pair), _ => AstError::bug_unimplemented(pair),
} }
} }
+6 -29
View File
@@ -2,7 +2,7 @@ use crate::{
Rule, Rule,
ast::*, ast::*,
ast_ensure, ast_expr, ast_ensure, ast_expr,
error::{AstError, AstResult, ErrorCode, IntoErr, collect_recovered}, error::{AstError, AstResult, IntoErr, collect_recovered},
parser::listen_rule, parser::listen_rule,
}; };
@@ -10,8 +10,10 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Block {
type Error = AstError<'a, Self>; type Error = AstError<'a, Self>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> { 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_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(); let mut inner = pair.clone().into_inner();
match rule { match rule {
Rule::statement => Statement::try_from(inner.next().unwrap()), Rule::statement | Rule::basic_stmt | Rule::control_flow => {
Statement::try_from(inner.next().unwrap())
Rule::expr_stmt => {
ast_expr!(Statement::Expression(inner.next().unwrap().try_into()))
} }
Rule::block => ast_expr!(Statement::Block(pair.try_into())), 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), 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( Rule::match_stmt => ast_expr!(Statement::Match(
inner.next().unwrap().try_into(), inner.next().unwrap().try_into(),
inner inner
@@ -107,23 +101,6 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Statement {
.collect::<AstResult<'a, Vec<_>>>(), .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), _ => AstError::bug_unimplemented(pair),
} }
} }
+2 -4
View File
@@ -8,8 +8,6 @@ use std::{
use cargo_metadata::{CompilerMessage, Message}; use cargo_metadata::{CompilerMessage, Message};
use mist_parser::rev_mapper::{RustMap, find_mapping, get_mapping}; use mist_parser::rev_mapper::{RustMap, find_mapping, get_mapping};
use crate::transpiler::Config;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct MistDiagnosticMessage { pub struct MistDiagnosticMessage {
pub message: String, pub message: String,
@@ -26,7 +24,7 @@ pub enum MistDiagnostic {
Rust(CompilerMessage), 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.remove(0);
args.insert(1, "--message-format=json".to_string()); 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 let mist_file = span
.file_name .file_name
.replacen(&config.output, &config.src, 1) .replacen(".mist/src", "src", 1)
.replace(".rs", ".mist"); .replace(".rs", ".mist");
let mist_path = root.join(&mist_file); let mist_path = root.join(&mist_file);
+24 -52
View File
@@ -1,8 +1,8 @@
use mist_parser::ast::{ use mist_parser::ast::{
Attribute, BinaryOp, Block, ClassItem, EnumItem, ExprPath, ExprPathSegment, Expression, Attribute, Block, ClassItem, EnumItem, ExprPath, ExprPathSegment, Expression, FieldDecl,
FieldDecl, FunctionDecl, Generic, GenericDecl, Generics, GenericsDecl, Identifier, ImplDecl, FunctionDecl, Generic, GenericDecl, Generics, GenericsDecl, Identifier, ImplDecl, Literal,
Literal, Path, Pattern, Postfix, Prefix, Spanned, Statement, StatementBranch, TopLevel, Path, Pattern, Postfix, Prefix, Spanned, Statement, StatementBranch, TopLevel, TopLevelKind,
TopLevelKind, TypeExpr, TypeExprKind, TypePostfix, VarDecl, VarDeclStmt, Visibility, TypeExpr, TypeExprKind, TypePostfix, VarDecl, VarDeclStmt, Visibility,
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@@ -169,6 +169,12 @@ impl GetRust for Expression {
match self { match self {
Expression::Path(path) => path.get_rust(), Expression::Path(path) => path.get_rust(),
Expression::Literal(literal) => literal.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 { Expression::Fix {
initial, initial,
prefixes, prefixes,
@@ -181,29 +187,7 @@ impl GetRust for Expression {
} }
// Safely integrated to handle the tree structure built by the Pratt Parser // Safely integrated to handle the tree structure built by the Pratt Parser
Expression::Binary { lhs, op, rhs } => { Expression::Binary { lhs, op, rhs } => {
let op_str = match op { format!("{} {} {}", lhs.get_rust(), op, rhs.get_rust())
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())
} }
} }
} }
@@ -313,6 +297,10 @@ impl GetRust for Postfix {
Postfix::As(ty) => format!(" as {}", ty.get_rust()), Postfix::As(ty) => format!(" as {}", ty.get_rust()),
Postfix::Try => String::from("?"), 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 { impl ToRust for Block {
fn to_rust(self, cg: &mut RustCodegen) { fn to_rust(self, cg: &mut RustCodegen) {
for stmt in self.0 { 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 { impl ToRust for Statement {
fn to_rust(self, cg: &mut RustCodegen) { fn to_rust(self, cg: &mut RustCodegen) {
match self { match self {
Statement::Expression(expr) => {
cg.add_indentedln(&format!("{};", expr.get_rust()));
}
Statement::Block(block) => { Statement::Block(block) => {
cg.add_indentedln("{"); cg.add_indentedln("{");
cg.indent += 1; cg.indent += 1;
@@ -625,20 +613,7 @@ impl ToRust for Statement {
.map(|e| format!(" = {}", e.get_rust())) .map(|e| format!(" = {}", e.get_rust()))
.unwrap_or_default(); .unwrap_or_default();
cg.add_indentedln(&format!("let {}{};", decl.get_rust(), init)); 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(),
));
} }
Statement::Match(expr, match_items) => { Statement::Match(expr, match_items) => {
@@ -733,14 +708,11 @@ impl ToRust for Statement {
Statement::Return(expr) => { Statement::Return(expr) => {
let val = expr.map(|e| e.get_rust()).unwrap_or_default(); 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::Break => cg.add_indentedln("break"),
Statement::Continue => cg.add_indentedln("continue;"), 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())),
} }
} }
} }
+52 -2
View File
@@ -1,5 +1,6 @@
use <std::process>; use <std::process>;
use <std::env>; use <std::env>;
use <std::fs>;
pub mod builder; pub mod builder;
pub mod codegen; pub mod codegen;
@@ -15,9 +16,12 @@ void main() {
match (args[1].as_str()) { match (args[1].as_str()) {
"run" | "build" | "check" | "r" | "b" | "c" => { "run" | "build" | "check" | "r" | "b" | "c" => {
var (config, root) = transpiler::build();
var root = transpiler::build();
println!(""); println!("");
if (builder::build(args, config, root)) {
if (builder::build(args, root)) {
println!("\x1b[32m\nBuild successful\x1b[0m"); println!("\x1b[32m\nBuild successful\x1b[0m");
} else { } else {
println!("\x1b[31m\nBuild failed\x1b[0m"); println!("\x1b[31m\nBuild failed\x1b[0m");
@@ -26,6 +30,9 @@ void main() {
"transpile" | "t" => { "transpile" | "t" => {
transpiler::build(); transpiler::build();
} }
"init" => {
init_project(args);
}
"version" | "--version" | "-v" => { "version" | "--version" | "-v" => {
println!("mist {}", env!("CARGO_PKG_VERSION")); println!("mist {}", env!("CARGO_PKG_VERSION"));
} }
@@ -55,6 +62,49 @@ void print_usage() {
println!( println!(
" \x1b[36m mist check\x1b[0m,\x1b[36m c\x1b[0m check the project in the current directory\n" " \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 version \x1b[0m print the compiler version\n");
println!(" \x1b[36m mist help\x1b[0m print this message\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
View File
@@ -6,25 +6,16 @@ use std::{
}; };
use mist_parser::error::ParseError; use mist_parser::error::ParseError;
use serde::Deserialize;
#[derive(Deserialize)] pub fn build() -> PathBuf {
pub struct Config {
pub src: String,
pub output: String,
}
pub fn build() -> (Config, PathBuf) {
let start = Instant::now(); let start = Instant::now();
let root = find_project_root().unwrap_or_else(|| { let root = std::env::current_dir()
panic!("error: could not find project root (mist.json)"); .ok()
}); .expect("Unable to find project root");
let config = load_config(&root); let src_dir = root.join("src");
let out_dir = root.join(".mist/src");
let src_dir = root.join(&config.src);
let out_dir = root.join(&config.output);
build_dir(&root, &src_dir, &src_dir, &out_dir); build_dir(&root, &src_dir, &src_dir, &out_dir);
@@ -35,7 +26,7 @@ pub fn build() -> (Config, PathBuf) {
elapsed elapsed
); );
(config, root) root
} }
fn build_dir(root: &Path, base_src: &Path, current_dir: &Path, out_dir: &Path) { 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 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")
}