Skip to content

Commit 6d88d3b

Browse files
committed
Begin compiler
Start of the compiler. The compiler does not directly produce the `.ksm` binary, but it gives the kRISC instructions to be placed in a binary. While it is currently far from done, it has output its first program (with help by manually* assmebling the binary): ```kLang func main: () -> () { print("Hello kOS!"); } ``` which is this in kRISC instructions: ```kRISC push ARG_MARKER push "Hello kOS!" call "", "print" ``` and the test kOS CPU output this: ```kOS Output Hello kOS! ```
1 parent 4a27584 commit 6d88d3b

2 files changed

Lines changed: 40 additions & 28 deletions

File tree

src/main.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ use clap::Parser;
77

88
mod lexer;
99
mod parser;
10+
mod compiler;
11+
1012

1113
/// A compiler for kLang
1214
#[derive(Debug, Parser)]
@@ -108,6 +110,16 @@ fn main() {
108110

109111
LOG.debug(&format!("\nParsed:\n\n{:?}\n", &ast));
110112

113+
let ksm = match compiler::parse_ast(ast) {
114+
Ok(ksm) => ksm,
115+
Err(e) => {
116+
LOG.surface(&format!("{e}"));
117+
std::process::exit(1);
118+
}
119+
};
120+
121+
LOG.debug(&format!("\nKSM:\n\n{:?}\n", &ksm));
122+
111123
todo!("Finish parsing & Compilation");
112124
}
113125

src/parser.rs

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ macro_rules! expect_lit_ident {
152152
};
153153
}
154154

155-
#[derive(Debug)]
155+
#[derive(Clone, Debug)]
156156
pub enum Stmt {
157157
Assembly(String),
158158
Expr(Expr),
@@ -168,15 +168,15 @@ pub enum Stmt {
168168
Break(Option<Expr>),
169169
}
170170

171-
#[derive(Debug)]
171+
#[derive(Clone, Debug)]
172172
pub struct Function {
173-
name: String,
174-
input: Vec<(String, Type)>,
175-
output: Type,
176-
body: Scope,
173+
pub name: String,
174+
pub input: Vec<(String, Type)>,
175+
pub output: Type,
176+
pub body: Scope,
177177
}
178178

179-
#[derive(Debug)]
179+
#[derive(Clone, Debug)]
180180
pub enum Expr {
181181
Call {
182182
name: String,
@@ -196,12 +196,12 @@ pub enum Expr {
196196
Lit(Lit),
197197
}
198198

199-
#[derive(Debug)]
199+
#[derive(Clone, Debug)]
200200
pub struct Scope {
201-
statements: Vec<Stmt>,
201+
pub statements: Vec<Stmt>,
202202
}
203203

204-
#[derive(Debug)]
204+
#[derive(Clone, Debug)]
205205
pub enum Lit {
206206
I16(i16),
207207
I32(i32),
@@ -213,7 +213,7 @@ pub enum Lit {
213213
Identifier(String),
214214
}
215215

216-
#[derive(Debug)]
216+
#[derive(Clone, Debug, PartialEq, Eq)]
217217
pub enum Type {
218218
I16,
219219
I32,
@@ -226,19 +226,19 @@ pub enum Type {
226226
Identifier(String),
227227
}
228228

229-
#[derive(Debug)]
229+
#[derive(Clone, Debug)]
230230
pub struct Constant {
231-
name: String,
232-
r#type: Type,
233-
expr: Expr,
231+
pub name: String,
232+
pub r#type: Type,
233+
pub expr: Expr,
234234
}
235235

236236
#[derive(Debug)]
237237
pub struct AST {
238-
statements: Vec<(Stmt, (usize, usize))>,
239-
consts: Vec<Constant>,
240-
macros: Vec<(String, Expr)>,
241-
types: Vec<(String, Type)>,
238+
pub functions: Vec<Function>,
239+
pub consts: Vec<Constant>,
240+
pub macros: Vec<(String, Expr)>,
241+
pub types: Vec<(String, Type)>,
242242
}
243243

244244
pub fn parse_tokens(tokens: Vec<DataToken>) -> Result<AST, ParseError> {
@@ -248,8 +248,7 @@ pub fn parse_tokens(tokens: Vec<DataToken>) -> Result<AST, ParseError> {
248248
}
249249

250250
fn parse_global(tokens: &mut tokenstream!()) -> Result<AST, ParseError> {
251-
let mut result: Vec<(Stmt, (usize, usize))> = Vec::new();
252-
251+
let mut functions: Vec<Function> = Vec::new();
253252
let mut consts: Vec<Constant> = Vec::new();
254253
let mut macros: Vec<(String, Expr)> = Vec::new();
255254
let mut types: Vec<(String, Type)> = Vec::new();
@@ -263,19 +262,15 @@ fn parse_global(tokens: &mut tokenstream!()) -> Result<AST, ParseError> {
263262
Token::Const => consts.push(parse_constant(tokens)?),
264263
Token::Macro => macros.push(parse_macro(tokens)?),
265264
Token::Type => types.push(parse_type_assign(tokens)?),
266-
Token::Func => result.push((Stmt::Func(parse_function(tokens)?), t.get_pos())),
265+
Token::Func => functions.push(parse_function(tokens)?),
267266
_ => return ParseError::new(&tokens.next().unwrap(), ParseErrorReason::UnexpectedToken, "An unexpected token in global scope, allowed tokens: `func`, `const`, `macro` and `type`")
268267
},
269268
None => break,
270269
}
271270
}
272271

273-
super::LOG.debug(&format!("\nGot constants: {:?}", consts));
274-
super::LOG.debug(&format!("Got macros: {:?}", macros));
275-
super::LOG.debug(&format!("Got types: {:?}", types));
276-
277272
Ok(AST {
278-
statements: result,
273+
functions,
279274
consts,
280275
macros,
281276
types,
@@ -379,6 +374,8 @@ fn parse_function(tokens: &mut tokenstream!()) -> Result<Function, ParseError> {
379374

380375
let body = parse_scope(tokens)?;
381376

377+
optional!(tokens, Terminator);
378+
382379
Ok(Function {
383380
name,
384381
input: inputs,
@@ -462,7 +459,10 @@ fn parse_scope(tokens: &mut tokenstream!()) -> Result<Scope, ParseError> {
462459
consume!(tokens, Terminator, "Break must be terminated with `;`, as it is currently a statement");
463460
},
464461
Token::Terminator => {super::LOG.explicit(&format!("Stray terminator `;`: {:?}", &tok)); tokens.next();},
465-
_ => statements.push(Stmt::Expr(parse_expr(tokens, 0)?))
462+
_ => {
463+
statements.push(Stmt::Expr(parse_expr(tokens, 0)?));
464+
optional!(tokens, Comma);
465+
}
466466
});
467467
}
468468
}

0 commit comments

Comments
 (0)