Successful work to compile, parse, and unparse basic Deimos.

This commit is contained in:
Jesse Brault 2025-05-15 09:40:39 -05:00
parent a9fe5b473c
commit a9457c1ab9
6 changed files with 42 additions and 20 deletions

View File

@ -0,0 +1,5 @@
fn main() {
println('Hello, World!');
let x = 'I greet you!';
println(x);
}

View File

@ -259,6 +259,7 @@ fn build_compilation_unit(compilation_unit_pair: Pair<Rule>) -> CompilationUnit
Rule::ModuleLevelDeclaration => { Rule::ModuleLevelDeclaration => {
declarations.push(build_module_level_declaration(inner_pair)); declarations.push(build_module_level_declaration(inner_pair));
} }
Rule::EOI => {}
_ => unreachable!(), _ => unreachable!(),
} }
} }
@ -842,7 +843,7 @@ macro_rules! build_binary_expression {
right: Box::new(right), right: Box::new(right),
}) })
} else { } else {
$left_fn(inner.next().unwrap()) expect_and_use(inner.next().unwrap(), $left_rule, $left_fn)
} }
}}; }};
} }
@ -1113,7 +1114,7 @@ fn build_boolean_literal(pair: Pair<Rule>) -> Literal {
fn build_single_quote_string(pair: Pair<Rule>) -> Literal { fn build_single_quote_string(pair: Pair<Rule>) -> Literal {
let inner_pair = pair.into_inner().next().unwrap(); let inner_pair = pair.into_inner().next().unwrap();
Literal::String(inner_pair.to_string()) Literal::String(inner_pair.as_span().as_str().to_string())
} }
fn build_double_quote_string(pair: Pair<Rule>) -> Literal { fn build_double_quote_string(pair: Pair<Rule>) -> Literal {

View File

@ -505,8 +505,10 @@ impl Unparse for FunctionDefinition {
write!(buf, " ")?; write!(buf, " ")?;
} }
write!(buf, "fn ")?; write!(buf, "fn ")?;
self.generics.unparse(buf)?; if !self.generics.is_empty() {
write!(buf, " ")?; self.generics.unparse(buf)?;
write!(buf, " ")?;
}
self.identifier.unparse(buf)?; self.identifier.unparse(buf)?;
self.parameters.unparse(buf)?; self.parameters.unparse(buf)?;
write!(buf, " ")?; write!(buf, " ")?;
@ -694,12 +696,13 @@ impl Unparse for FieldDeclaration {
impl Unparse for BlockStatement { impl Unparse for BlockStatement {
fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result {
write!(buf, "{{")?; write!(buf, "{{\n")?;
for statement in &self.statements { for statement in &self.statements {
statement.unparse(buf)?; statement.unparse(buf)?;
} }
if let Some(expression) = &self.expression { if let Some(expression) = &self.expression {
expression.unparse(buf)?; expression.unparse(buf)?;
write!(buf, "\n")?;
} }
write!(buf, "}}")?; write!(buf, "}}")?;
unparse_ok!() unparse_ok!()

View File

@ -1,9 +1,22 @@
use std::path::PathBuf; use std::path::PathBuf;
use pest::Parser;
use deimos::ast::build::build_ast; use deimos::ast::build::build_ast;
use deimos::ast::unparse::Unparse;
use deimos::parser::{DeimosParser, Rule};
pub fn dump_ast(path: &PathBuf) { pub fn unparse(path: &PathBuf) {
let src = std::fs::read_to_string(path).expect(&format!("Could not read {:?}", path)); let src = std::fs::read_to_string(path).expect(&format!("Could not read {:?}", path));
let ast = build_ast(&src); let parse_result = DeimosParser::parse(Rule::CompilationUnit, &src);
println!("{:?}", ast); match parse_result {
Ok(mut pairs) => {
let compilation_unit_pair = pairs.next().unwrap();
let compilation_unit = build_ast(compilation_unit_pair);
let mut out = String::new();
compilation_unit.unparse(&mut out).expect("Failed to write to string.");
println!("{}", out);
},
Err(e) => {
eprintln!("{}", e);
}
}
} }

View File

@ -2,7 +2,7 @@ mod ast_dump;
use std::path::PathBuf; use std::path::PathBuf;
use ast_dump::dump_ast; use ast_dump::unparse;
use clap::{Parser, Subcommand}; use clap::{Parser, Subcommand};
#[derive(Debug, Parser)] #[derive(Debug, Parser)]
@ -16,15 +16,15 @@ struct Cli {
#[derive(Debug, Subcommand)] #[derive(Debug, Subcommand)]
enum Commands { enum Commands {
#[command(arg_required_else_help = true)] #[command(arg_required_else_help = true)]
AstDump { paths: Vec<PathBuf> }, Unparse { paths: Vec<PathBuf> },
} }
fn main() { fn main() {
let args = Cli::parse(); let args = Cli::parse();
match args.command { match args.command {
Commands::AstDump { paths } => { Commands::Unparse { paths } => {
for path in paths { for path in paths {
dump_ast(&path); unparse(&path);
} }
} }
} }

View File

@ -584,7 +584,7 @@ AndExpression = {
} }
ComparisonExpression = { ComparisonExpression = {
AdditiveExpression ShiftExpression
~ ( ~ (
( Greater | Less | GreaterEqual | LessEqual | EqualTo | NotEqualTo ) ( Greater | Less | GreaterEqual | LessEqual | EqualTo | NotEqualTo )
~ Expression ~ Expression
@ -762,7 +762,7 @@ StringLiteral = {
| BacktickString | BacktickString
} }
SingleQuoteString = ${ "'" ~ StringInner ~ "'" } SingleQuoteString = { "'" ~ StringInner? ~ "'" }
DoubleQuoteString = { DoubleQuoteString = {
"\"" "\""
@ -771,10 +771,10 @@ DoubleQuoteString = {
~ "\"" ~ "\""
} }
StringInner = @{ StringChar* } StringInner = @{ StringChar+ }
StringChar = { StringChar = {
!( "\"" | "\\" ) ~ ANY !( "\'" | "\\" ) ~ ANY
| "\\" ~ ( "'" | "\\" | "/" | "b" | "f" | "n" | "r" | "t" ) | "\\" ~ ( "'" | "\\" | "/" | "b" | "f" | "n" | "r" | "t" )
| "\\" ~ ( "u" ~ ASCII_HEX_DIGIT{4} ) | "\\" ~ ( "u" ~ ASCII_HEX_DIGIT{4} )
} }
@ -794,15 +794,15 @@ DStringExpression = {
BacktickString = { BacktickString = {
"`" "`"
~ ( DStringInner? ~ DStringExpression )* ~ ( BacktickInner? ~ DStringExpression )*
~ DStringInner? ~ BacktickInner?
~ "`" ~ "`"
} }
BacktickInner = @{ BacktickStringChar+ } BacktickInner = @{ BacktickStringChar+ }
BacktickStringChar = { BacktickStringChar = {
!( "\"" | "\\" ) ~ ANY !( "\\`" | "\\" ) ~ ANY
| "\\" ~ ( "`" | "\\" | "/" | "b" | "f" | "n" | "r" | "t" | "$" ) | "\\" ~ ( "`" | "\\" | "/" | "b" | "f" | "n" | "r" | "t" | "$" )
| "\\" ~ ( "u" ~ ASCII_HEX_DIGIT{4} ) | "\\" ~ ( "u" ~ ASCII_HEX_DIGIT{4} )
} }