Fiddle with names a bit
This commit is contained in:
parent
8a32e66ba8
commit
a66fc61c07
@ -11,13 +11,13 @@ fn main() {
|
|||||||
kind: FunctionDefinitionKind::Local(
|
kind: FunctionDefinitionKind::Local(
|
||||||
Block {
|
Block {
|
||||||
statements: vec![Statement(
|
statements: vec![Statement(
|
||||||
StatementKind::If(IfExpression(
|
StmtKind::If(IfExpression(
|
||||||
// If N < 3
|
// If N < 3
|
||||||
Box::new(Expression(
|
Box::new(Expression(
|
||||||
ExpressionKind::BinOp(
|
ExprKind::BinOp(
|
||||||
BinaryOperator::Logic(LogicOperator::GreaterThan),
|
BinaryOperator::Logic(LogicOperator::GreaterThan),
|
||||||
Box::new(Expression(
|
Box::new(Expression(
|
||||||
ExpressionKind::Variable(VariableReference(
|
ExprKind::Variable(VariableReference(
|
||||||
TypeKind::I32,
|
TypeKind::I32,
|
||||||
"N".to_string(),
|
"N".to_string(),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
@ -25,7 +25,7 @@ fn main() {
|
|||||||
Default::default(),
|
Default::default(),
|
||||||
)),
|
)),
|
||||||
Box::new(Expression(
|
Box::new(Expression(
|
||||||
ExpressionKind::Literal(Literal::I32(2)),
|
ExprKind::Literal(Literal::I32(2)),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
@ -38,30 +38,26 @@ fn main() {
|
|||||||
ReturnKind::HardReturn,
|
ReturnKind::HardReturn,
|
||||||
// return fibonacci(n-1) + fibonacci(n-2)
|
// return fibonacci(n-1) + fibonacci(n-2)
|
||||||
Box::new(Expression(
|
Box::new(Expression(
|
||||||
ExpressionKind::BinOp(
|
ExprKind::BinOp(
|
||||||
BinaryOperator::Add,
|
BinaryOperator::Add,
|
||||||
// fibonacci(n-1)
|
// fibonacci(n-1)
|
||||||
Box::new(Expression(
|
Box::new(Expression(
|
||||||
ExpressionKind::FunctionCall(FunctionCall {
|
ExprKind::FunctionCall(FunctionCall {
|
||||||
name: fibonacci_name.clone(),
|
name: fibonacci_name.clone(),
|
||||||
return_type: TypeKind::I32,
|
return_type: TypeKind::I32,
|
||||||
parameters: vec![Expression(
|
parameters: vec![Expression(
|
||||||
ExpressionKind::BinOp(
|
ExprKind::BinOp(
|
||||||
BinaryOperator::Minus,
|
BinaryOperator::Minus,
|
||||||
Box::new(Expression(
|
Box::new(Expression(
|
||||||
ExpressionKind::Variable(
|
ExprKind::Variable(VariableReference(
|
||||||
VariableReference(
|
TypeKind::I32,
|
||||||
TypeKind::I32,
|
fibonacci_n.clone(),
|
||||||
fibonacci_n.clone(),
|
Default::default(),
|
||||||
Default::default(),
|
)),
|
||||||
),
|
|
||||||
),
|
|
||||||
Default::default(),
|
Default::default(),
|
||||||
)),
|
)),
|
||||||
Box::new(Expression(
|
Box::new(Expression(
|
||||||
ExpressionKind::Literal(Literal::I32(
|
ExprKind::Literal(Literal::I32(1)),
|
||||||
1,
|
|
||||||
)),
|
|
||||||
Default::default(),
|
Default::default(),
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
@ -72,26 +68,22 @@ fn main() {
|
|||||||
)),
|
)),
|
||||||
// fibonacci(n-2)
|
// fibonacci(n-2)
|
||||||
Box::new(Expression(
|
Box::new(Expression(
|
||||||
ExpressionKind::FunctionCall(FunctionCall {
|
ExprKind::FunctionCall(FunctionCall {
|
||||||
name: fibonacci_name.clone(),
|
name: fibonacci_name.clone(),
|
||||||
return_type: TypeKind::I32,
|
return_type: TypeKind::I32,
|
||||||
parameters: vec![Expression(
|
parameters: vec![Expression(
|
||||||
ExpressionKind::BinOp(
|
ExprKind::BinOp(
|
||||||
BinaryOperator::Minus,
|
BinaryOperator::Minus,
|
||||||
Box::new(Expression(
|
Box::new(Expression(
|
||||||
ExpressionKind::Variable(
|
ExprKind::Variable(VariableReference(
|
||||||
VariableReference(
|
TypeKind::I32,
|
||||||
TypeKind::I32,
|
fibonacci_n.clone(),
|
||||||
fibonacci_n.clone(),
|
Default::default(),
|
||||||
Default::default(),
|
)),
|
||||||
),
|
|
||||||
),
|
|
||||||
Default::default(),
|
Default::default(),
|
||||||
)),
|
)),
|
||||||
Box::new(Expression(
|
Box::new(Expression(
|
||||||
ExpressionKind::Literal(Literal::I32(
|
ExprKind::Literal(Literal::I32(2)),
|
||||||
2,
|
|
||||||
)),
|
|
||||||
Default::default(),
|
Default::default(),
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
@ -104,7 +96,7 @@ fn main() {
|
|||||||
Default::default(),
|
Default::default(),
|
||||||
)),
|
)),
|
||||||
)),
|
)),
|
||||||
range: Default::default(),
|
meta: Default::default(),
|
||||||
},
|
},
|
||||||
// No else-block
|
// No else-block
|
||||||
None,
|
None,
|
||||||
@ -115,11 +107,11 @@ fn main() {
|
|||||||
return_expression: Some((
|
return_expression: Some((
|
||||||
ReturnKind::SoftReturn,
|
ReturnKind::SoftReturn,
|
||||||
Box::new(Expression(
|
Box::new(Expression(
|
||||||
ExpressionKind::Literal(Literal::I32(1)),
|
ExprKind::Literal(Literal::I32(1)),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
)),
|
)),
|
||||||
)),
|
)),
|
||||||
range: Default::default(),
|
meta: Default::default(),
|
||||||
},
|
},
|
||||||
Default::default(),
|
Default::default(),
|
||||||
),
|
),
|
||||||
@ -134,18 +126,18 @@ fn main() {
|
|||||||
return_expression: Some((
|
return_expression: Some((
|
||||||
ReturnKind::SoftReturn,
|
ReturnKind::SoftReturn,
|
||||||
Box::new(Expression(
|
Box::new(Expression(
|
||||||
ExpressionKind::FunctionCall(FunctionCall {
|
ExprKind::FunctionCall(FunctionCall {
|
||||||
name: fibonacci_name.clone(),
|
name: fibonacci_name.clone(),
|
||||||
return_type: TypeKind::I32,
|
return_type: TypeKind::I32,
|
||||||
parameters: vec![Expression(
|
parameters: vec![Expression(
|
||||||
ExpressionKind::Literal(Literal::I32(5)),
|
ExprKind::Literal(Literal::I32(5)),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
)],
|
)],
|
||||||
}),
|
}),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
)),
|
)),
|
||||||
)),
|
)),
|
||||||
range: Default::default(),
|
meta: Default::default(),
|
||||||
},
|
},
|
||||||
Default::default(),
|
Default::default(),
|
||||||
),
|
),
|
||||||
|
@ -102,14 +102,14 @@ impl<'ctx> Scope<'ctx> {
|
|||||||
impl mir::Statement {
|
impl mir::Statement {
|
||||||
pub fn codegen<'ctx>(&self, scope: &mut Scope<'ctx>) -> Option<Value<'ctx>> {
|
pub fn codegen<'ctx>(&self, scope: &mut Scope<'ctx>) -> Option<Value<'ctx>> {
|
||||||
match &self.0 {
|
match &self.0 {
|
||||||
mir::StatementKind::Let(VariableReference(_, name, _), expression) => {
|
mir::StmtKind::Let(VariableReference(_, name, _), expression) => {
|
||||||
let value = expression.codegen(scope).unwrap();
|
let value = expression.codegen(scope).unwrap();
|
||||||
scope.stack_values.insert(name.clone(), value);
|
scope.stack_values.insert(name.clone(), value);
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
mir::StatementKind::If(if_expression) => if_expression.codegen(scope),
|
mir::StmtKind::If(if_expression) => if_expression.codegen(scope),
|
||||||
mir::StatementKind::Import(_) => todo!(),
|
mir::StmtKind::Import(_) => todo!(),
|
||||||
mir::StatementKind::Expression(expression) => {
|
mir::StmtKind::Expression(expression) => {
|
||||||
let value = expression.codegen(scope).unwrap();
|
let value = expression.codegen(scope).unwrap();
|
||||||
Some(value)
|
Some(value)
|
||||||
}
|
}
|
||||||
@ -178,15 +178,15 @@ impl mir::IfExpression {
|
|||||||
impl mir::Expression {
|
impl mir::Expression {
|
||||||
pub fn codegen<'ctx>(&self, scope: &mut Scope<'ctx>) -> Option<Value<'ctx>> {
|
pub fn codegen<'ctx>(&self, scope: &mut Scope<'ctx>) -> Option<Value<'ctx>> {
|
||||||
match &self.0 {
|
match &self.0 {
|
||||||
mir::ExpressionKind::Variable(varref) => {
|
mir::ExprKind::Variable(varref) => {
|
||||||
let v = scope
|
let v = scope
|
||||||
.stack_values
|
.stack_values
|
||||||
.get(&varref.1)
|
.get(&varref.1)
|
||||||
.expect("Variable reference not found?!");
|
.expect("Variable reference not found?!");
|
||||||
Some(v.clone())
|
Some(v.clone())
|
||||||
}
|
}
|
||||||
mir::ExpressionKind::Literal(lit) => Some(lit.codegen(scope.context)),
|
mir::ExprKind::Literal(lit) => Some(lit.codegen(scope.context)),
|
||||||
mir::ExpressionKind::BinOp(binop, lhs_exp, rhs_exp) => {
|
mir::ExprKind::BinOp(binop, lhs_exp, rhs_exp) => {
|
||||||
let lhs = lhs_exp.codegen(scope).expect("lhs has no return value");
|
let lhs = lhs_exp.codegen(scope).expect("lhs has no return value");
|
||||||
let rhs = rhs_exp.codegen(scope).expect("rhs has no return value");
|
let rhs = rhs_exp.codegen(scope).expect("rhs has no return value");
|
||||||
Some(match binop {
|
Some(match binop {
|
||||||
@ -203,7 +203,7 @@ impl mir::Expression {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
mir::ExpressionKind::FunctionCall(call) => {
|
mir::ExprKind::FunctionCall(call) => {
|
||||||
let params = call
|
let params = call
|
||||||
.parameters
|
.parameters
|
||||||
.iter()
|
.iter()
|
||||||
@ -215,8 +215,8 @@ impl mir::Expression {
|
|||||||
.expect("function not found!");
|
.expect("function not found!");
|
||||||
Some(scope.block.call(callee, params, "call").unwrap())
|
Some(scope.block.call(callee, params, "call").unwrap())
|
||||||
}
|
}
|
||||||
mir::ExpressionKind::If(if_expression) => if_expression.codegen(scope),
|
mir::ExprKind::If(if_expression) => if_expression.codegen(scope),
|
||||||
mir::ExpressionKind::Block(block) => {
|
mir::ExprKind::Block(block) => {
|
||||||
let mut inner_scope = scope.with_block(scope.function.block("inner"));
|
let mut inner_scope = scope.with_block(scope.function.block("inner"));
|
||||||
if let Some(ret) = block.codegen(&mut inner_scope) {
|
if let Some(ret) = block.codegen(&mut inner_scope) {
|
||||||
inner_scope.block.br(&scope.block);
|
inner_scope.block.br(&scope.block);
|
||||||
|
@ -9,6 +9,19 @@ use crate::token_stream::TokenRange;
|
|||||||
|
|
||||||
pub mod types;
|
pub mod types;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct Metadata {
|
||||||
|
range: TokenRange,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Metadata {
|
||||||
|
fn default() -> Self {
|
||||||
|
Metadata {
|
||||||
|
range: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum TypeKind {
|
pub enum TypeKind {
|
||||||
I32,
|
I32,
|
||||||
@ -59,11 +72,11 @@ pub enum ReturnKind {
|
|||||||
SoftReturn,
|
SoftReturn,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct VariableReference(pub TypeKind, pub String, pub TokenRange);
|
pub struct VariableReference(pub TypeKind, pub String, pub Metadata);
|
||||||
|
|
||||||
pub struct Import(pub String, pub TokenRange);
|
pub struct Import(pub String, pub Metadata);
|
||||||
|
|
||||||
pub enum ExpressionKind {
|
pub enum ExprKind {
|
||||||
Variable(VariableReference),
|
Variable(VariableReference),
|
||||||
Literal(Literal),
|
Literal(Literal),
|
||||||
BinOp(BinaryOperator, Box<Expression>, Box<Expression>),
|
BinOp(BinaryOperator, Box<Expression>, Box<Expression>),
|
||||||
@ -72,7 +85,7 @@ pub enum ExpressionKind {
|
|||||||
Block(Block),
|
Block(Block),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Expression(pub ExpressionKind, pub TokenRange);
|
pub struct Expression(pub ExprKind, pub Metadata);
|
||||||
|
|
||||||
/// Condition, Then, Else
|
/// Condition, Then, Else
|
||||||
pub struct IfExpression(pub Box<Expression>, pub Block, pub Option<Block>);
|
pub struct IfExpression(pub Box<Expression>, pub Block, pub Option<Block>);
|
||||||
@ -91,7 +104,7 @@ pub struct FunctionDefinition {
|
|||||||
|
|
||||||
pub enum FunctionDefinitionKind {
|
pub enum FunctionDefinitionKind {
|
||||||
/// Actual definition block and surrounding signature range
|
/// Actual definition block and surrounding signature range
|
||||||
Local(Block, TokenRange),
|
Local(Block, Metadata),
|
||||||
/// Return Type
|
/// Return Type
|
||||||
Extern(TypeKind),
|
Extern(TypeKind),
|
||||||
}
|
}
|
||||||
@ -100,12 +113,12 @@ pub struct Block {
|
|||||||
/// List of non-returning statements
|
/// List of non-returning statements
|
||||||
pub statements: Vec<Statement>,
|
pub statements: Vec<Statement>,
|
||||||
pub return_expression: Option<(ReturnKind, Box<Expression>)>,
|
pub return_expression: Option<(ReturnKind, Box<Expression>)>,
|
||||||
pub range: TokenRange,
|
pub meta: Metadata,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Statement(pub StatementKind, pub TokenRange);
|
pub struct Statement(pub StmtKind, pub Metadata);
|
||||||
|
|
||||||
pub enum StatementKind {
|
pub enum StmtKind {
|
||||||
/// Variable name+type, evaluation
|
/// Variable name+type, evaluation
|
||||||
Let(VariableReference, Expression),
|
Let(VariableReference, Expression),
|
||||||
If(IfExpression),
|
If(IfExpression),
|
||||||
|
@ -16,26 +16,26 @@ impl ReturnType for Block {
|
|||||||
fn return_type(&self) -> Result<TypeKind, ReturnTypeOther> {
|
fn return_type(&self) -> Result<TypeKind, ReturnTypeOther> {
|
||||||
self.return_expression
|
self.return_expression
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.ok_or(ReturnTypeOther::NoBlockReturn(self.range.clone()))
|
.ok_or(ReturnTypeOther::NoBlockReturn(self.meta.range))
|
||||||
.and_then(|(_, stmt)| stmt.return_type())
|
.and_then(|(_, stmt)| stmt.return_type())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReturnType for Statement {
|
impl ReturnType for Statement {
|
||||||
fn return_type(&self) -> Result<TypeKind, ReturnTypeOther> {
|
fn return_type(&self) -> Result<TypeKind, ReturnTypeOther> {
|
||||||
use StatementKind::*;
|
use StmtKind::*;
|
||||||
match &self.0 {
|
match &self.0 {
|
||||||
Expression(e) => e.return_type(),
|
Expression(e) => e.return_type(),
|
||||||
If(e) => e.return_type(),
|
If(e) => e.return_type(),
|
||||||
Import(_) => Err(ReturnTypeOther::Import(self.1)),
|
Import(_) => Err(ReturnTypeOther::Import(self.1.range)),
|
||||||
Let(_, _) => Err(ReturnTypeOther::Let(self.1)),
|
Let(_, _) => Err(ReturnTypeOther::Let(self.1.range)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReturnType for Expression {
|
impl ReturnType for Expression {
|
||||||
fn return_type(&self) -> Result<TypeKind, ReturnTypeOther> {
|
fn return_type(&self) -> Result<TypeKind, ReturnTypeOther> {
|
||||||
use ExpressionKind::*;
|
use ExprKind::*;
|
||||||
match &self.0 {
|
match &self.0 {
|
||||||
Literal(lit) => Ok(lit.as_type()),
|
Literal(lit) => Ok(lit.as_type()),
|
||||||
Variable(var) => var.return_type(),
|
Variable(var) => var.return_type(),
|
||||||
|
@ -177,6 +177,17 @@ impl Default for TokenRange {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl std::ops::Add for TokenRange {
|
||||||
|
type Output = TokenRange;
|
||||||
|
|
||||||
|
fn add(self, rhs: Self) -> Self::Output {
|
||||||
|
TokenRange {
|
||||||
|
start: self.start.min(rhs.start),
|
||||||
|
end: self.end.min(rhs.end),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
#[error("Expected {} at Ln {}, Col {}, got {:?}", .0, (.2).1, (.2).0, .1)]
|
#[error("Expected {} at Ln {}, Col {}, got {:?}", .0, (.2).1, (.2).0, .1)]
|
||||||
|
Loading…
Reference in New Issue
Block a user