added operator typehinting
This commit is contained in:
parent
e80a69fb41
commit
2d7cf80101
|
@ -64,7 +64,9 @@ main() = int {
|
||||||
|
|
||||||
if let Ok(mut tokens) = tokenize(source, &mut diagnostics) {
|
if let Ok(mut tokens) = tokenize(source, &mut diagnostics) {
|
||||||
if let Ok((fs, ds)) = parse(&mut tokens, &mut diagnostics, &settings) {
|
if let Ok((fs, ds)) = parse(&mut tokens, &mut diagnostics, &settings) {
|
||||||
vmrt::compile(&fs, &ds);
|
if let Ok(prog) = vmrt::compile(&fs, &ds) {
|
||||||
|
vmrt::execute(&prog);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -146,6 +146,21 @@ impl<'a> Declr<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn main() -> Self {
|
||||||
|
let mut main = Declr {
|
||||||
|
name: Some("main"),
|
||||||
|
args: None,
|
||||||
|
results: true,
|
||||||
|
result_typ: Some(Prim::Int),
|
||||||
|
info: None,
|
||||||
|
uuid: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
main.gen_uuid();
|
||||||
|
|
||||||
|
main
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_arg_ord(&self, name: &str) -> usize {
|
pub fn get_arg_ord(&self, name: &str) -> usize {
|
||||||
if let Some(args) = self.args.as_ref() {
|
if let Some(args) = self.args.as_ref() {
|
||||||
for (x, arg) in args.iter().enumerate() {
|
for (x, arg) in args.iter().enumerate() {
|
||||||
|
|
|
@ -493,7 +493,7 @@ fn collapse_operation(
|
||||||
) -> Result<(), ()> {
|
) -> Result<(), ()> {
|
||||||
|
|
||||||
match operation {
|
match operation {
|
||||||
Token::Operator(op, _, dbginf) => op.operate(operands, &dbginf, diagnostics)?,
|
Token::Operator(op, ref mut typehint, dbginf) => *typehint = Some(op.operate(operands, &dbginf, diagnostics)?),
|
||||||
Token::Assign(name, ref mut typ, dbginf) => {
|
Token::Assign(name, ref mut typ, dbginf) => {
|
||||||
check_var_typ(typ, operands, &dbginf, diagnostics)?;
|
check_var_typ(typ, operands, &dbginf, diagnostics)?;
|
||||||
scope.decl_var((*name).to_owned(), typ.clone());
|
scope.decl_var((*name).to_owned(), typ.clone());
|
||||||
|
|
|
@ -115,13 +115,23 @@ impl Operator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn operation_type(operands: &[Prim]) -> Option<Prim> {
|
||||||
|
let mut typ = None;
|
||||||
|
for op in operands.iter() {
|
||||||
|
op.merge_types(&mut typ);
|
||||||
|
}
|
||||||
|
|
||||||
|
typ
|
||||||
|
}
|
||||||
|
|
||||||
fn present_types(
|
fn present_types(
|
||||||
|
&self,
|
||||||
operands: &[Prim],
|
operands: &[Prim],
|
||||||
types: &[Prim],
|
types: &[Prim],
|
||||||
r#yield: Prim,
|
r#yield: Prim,
|
||||||
info: &DebugInfo,
|
info: &DebugInfo,
|
||||||
diagnostics: &mut crate::parser::data::Diagnostics,
|
diagnostics: &mut crate::parser::data::Diagnostics,
|
||||||
) -> Result<Option<Prim>, ()> {
|
) -> Result<(Option<Prim>, Option<Prim>), ()> {
|
||||||
|
|
||||||
if operands.len() < types.len() {
|
if operands.len() < types.len() {
|
||||||
diagnostics.set_err(info, crate::msg::ERR74, format!(
|
diagnostics.set_err(info, crate::msg::ERR74, format!(
|
||||||
|
@ -134,27 +144,30 @@ impl Operator {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (x, typ) in types.iter().enumerate() {
|
for (x, typ) in types.iter().enumerate() {
|
||||||
if typ != &operands[x] {
|
if !typ.is_equal(operands[x]) {
|
||||||
return Ok(None);
|
return Ok((None, None));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(Some(r#yield))
|
|
||||||
|
// this combination fits
|
||||||
|
Ok((Some(r#yield), Self::operation_type(types) ))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_types(
|
fn check_types(
|
||||||
|
&self,
|
||||||
operands: &[Prim],
|
operands: &[Prim],
|
||||||
types: &[(&[Prim], Prim)],
|
types: &[(&[Prim], Prim)],
|
||||||
dbginf: &DebugInfo,
|
dbginf: &DebugInfo,
|
||||||
diagnostics: &mut crate::parser::data::Diagnostics,
|
diagnostics: &mut crate::parser::data::Diagnostics,
|
||||||
) -> Result<Option<Prim>,()> {
|
) -> Result<(Option<Prim>, Option<Prim>),()> {
|
||||||
for combination in types.iter() {
|
for combination in types.iter() {
|
||||||
if let Some(result) =
|
if let (result, hint) =
|
||||||
Self::present_types(operands, combination.0, combination.1, dbginf, diagnostics)?
|
self.present_types(operands, combination.0, combination.1, dbginf, diagnostics)?
|
||||||
{
|
{
|
||||||
return Ok(Some(result));
|
return Ok((result, hint));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(None)
|
Ok((None, None))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn operate(
|
pub fn operate(
|
||||||
|
@ -162,36 +175,36 @@ impl Operator {
|
||||||
operands: &mut Vec<Prim>,
|
operands: &mut Vec<Prim>,
|
||||||
info: &DebugInfo,
|
info: &DebugInfo,
|
||||||
diagnostics: &mut crate::parser::data::Diagnostics,
|
diagnostics: &mut crate::parser::data::Diagnostics,
|
||||||
) -> Result<(),()> {
|
) -> Result<Prim,()> {
|
||||||
// TODO: insert type hint
|
// TODO: insert type hint
|
||||||
match self {
|
match self {
|
||||||
Operator::Add | Operator::Sub | Operator::Mul | Operator::Div => {
|
Operator::Add | Operator::Sub | Operator::Mul | Operator::Div => {
|
||||||
let types_valid =
|
let (types_valid, hint) =
|
||||||
Self::check_types(operands, ARITHMETIC_TYPES, info, diagnostics)?;
|
self.check_types(operands, ARITHMETIC_TYPES, info, diagnostics)?;
|
||||||
|
|
||||||
if let Some(result) = types_valid {
|
if let Some(result) = types_valid {
|
||||||
operands.pop();
|
operands.pop();
|
||||||
operands.pop();
|
operands.pop();
|
||||||
operands.push(result);
|
operands.push(result);
|
||||||
return Ok(());
|
return Ok(hint.unwrap());
|
||||||
} else {
|
} else {
|
||||||
diagnostics.set_err(info, crate::msg::ERR73, "expected two numbers");
|
diagnostics.set_err(info, crate::msg::ERR73, "expected two numbers");
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Operator::And | Operator::Or | Operator::Xor => {
|
Operator::And | Operator::Or | Operator::Xor => {
|
||||||
let types_valid = Self::check_types(
|
let types_valid = self.check_types(
|
||||||
operands,
|
operands,
|
||||||
&[(&[Prim::Bool, Prim::Bool], Prim::Bool)],
|
&[(&[Prim::Bool, Prim::Bool], Prim::Bool)],
|
||||||
info,
|
info,
|
||||||
diagnostics,
|
diagnostics,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
if let Some(result) = types_valid {
|
if let (Some(result), Some(hint)) = types_valid {
|
||||||
operands.pop();
|
operands.pop();
|
||||||
operands.pop();
|
operands.pop();
|
||||||
operands.push(result);
|
operands.push(result);
|
||||||
return Ok(())
|
return Ok(hint)
|
||||||
} else {
|
} else {
|
||||||
diagnostics.set_err(info, crate::msg::ERR73, "expected two booleans");
|
diagnostics.set_err(info, crate::msg::ERR73, "expected two booleans");
|
||||||
return Err(());
|
return Err(());
|
||||||
|
@ -203,7 +216,7 @@ impl Operator {
|
||||||
| Operator::Gt
|
| Operator::Gt
|
||||||
| Operator::GtEq
|
| Operator::GtEq
|
||||||
| Operator::LtEq => {
|
| Operator::LtEq => {
|
||||||
let types_valid = Self::check_types(
|
let types_valid = self.check_types(
|
||||||
operands,
|
operands,
|
||||||
&[
|
&[
|
||||||
(&[Prim::Int, Prim::Int], Prim::Bool),
|
(&[Prim::Int, Prim::Int], Prim::Bool),
|
||||||
|
@ -225,11 +238,11 @@ impl Operator {
|
||||||
diagnostics,
|
diagnostics,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
if let Some(result) = types_valid {
|
if let (Some(result), Some(hint)) = types_valid {
|
||||||
operands.pop();
|
operands.pop();
|
||||||
operands.pop();
|
operands.pop();
|
||||||
operands.push(result);
|
operands.push(result);
|
||||||
return Ok(());
|
return Ok(hint);
|
||||||
} else {
|
} else {
|
||||||
diagnostics.set_err(info, crate::msg::ERR73, "expected either two booleans or two numbers");
|
diagnostics.set_err(info, crate::msg::ERR73, "expected either two booleans or two numbers");
|
||||||
return Err(());
|
return Err(());
|
||||||
|
@ -315,6 +328,16 @@ impl Prim {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn merge_types(&self, current: &mut Option<Prim>) {
|
||||||
|
if let Some(prim) = current {
|
||||||
|
if !prim.is_equal(*self) {
|
||||||
|
*current = None;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*current = Some(*self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_equal(&self, value: Prim) -> bool {
|
pub fn is_equal(&self, value: Prim) -> bool {
|
||||||
return match self {
|
return match self {
|
||||||
Prim::Bool => *self == value,
|
Prim::Bool => *self == value,
|
||||||
|
@ -486,7 +509,7 @@ impl<'a> std::fmt::Display for Token<'a> {
|
||||||
Token::Type(t, _) => f.write_fmt(format_args!("__Type {:?}", t)),
|
Token::Type(t, _) => f.write_fmt(format_args!("__Type {:?}", t)),
|
||||||
Token::Word(w, _) => f.write_fmt(format_args!("__Word {:?}", w)),
|
Token::Word(w, _) => f.write_fmt(format_args!("__Word {:?}", w)),
|
||||||
Token::Delemiter(d, _) => f.write_fmt(format_args!("__Delemiter {:?}", d)),
|
Token::Delemiter(d, _) => f.write_fmt(format_args!("__Delemiter {:?}", d)),
|
||||||
Token::Operator(o, _, _) => f.write_fmt(format_args!("{:?}", o)),
|
Token::Operator(o, hint, _) => f.write_fmt(format_args!("{:?} {:?}", o, hint.unwrap())),
|
||||||
Token::Number(n, hint, _) => f.write_fmt(format_args!("Load {:?} {}", hint, n)),
|
Token::Number(n, hint, _) => f.write_fmt(format_args!("Load {:?} {}", hint, n)),
|
||||||
Token::LineBreak(_) => f.write_str("__Line-break"),
|
Token::LineBreak(_) => f.write_str("__Line-break"),
|
||||||
Token::Func(name, _) => f.write_fmt(format_args!("Call {}", name)),
|
Token::Func(name, _) => f.write_fmt(format_args!("Call {}", name)),
|
||||||
|
|
111
src/vmrt/mod.rs
111
src/vmrt/mod.rs
|
@ -1,13 +1,13 @@
|
||||||
use std::collections::{VecDeque, HashMap};
|
use std::collections::{VecDeque, HashMap};
|
||||||
|
|
||||||
use crate::{parser::data::*, token::{Token, NumHint}};
|
use crate::{parser::data::*, token::{Token, NumHint, Prim}};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
enum Data {
|
enum Data {
|
||||||
Int(i64),
|
Int(i64),
|
||||||
Rat(f64),
|
Rat(f64),
|
||||||
Bool(bool),
|
Bool(bool),
|
||||||
Off(usize),
|
Off(u64),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -64,7 +64,7 @@ enum Instr {
|
||||||
/// delete the last value from stack
|
/// delete the last value from stack
|
||||||
Pop,
|
Pop,
|
||||||
|
|
||||||
/// push the value stored at offset onto the stack
|
/// push the value stored at offset from the local stack onto the local stack
|
||||||
Load(usize),
|
Load(usize),
|
||||||
/// store the value stored at the stack[0](offset) stack[1](value) onto the stack
|
/// store the value stored at the stack[0](offset) stack[1](value) onto the stack
|
||||||
Store,
|
Store,
|
||||||
|
@ -91,10 +91,15 @@ enum Instr {
|
||||||
/// +----------------------------------+
|
/// +----------------------------------+
|
||||||
/// | Parameter (n) |
|
/// | Parameter (n) |
|
||||||
/// +----------------------------------+
|
/// +----------------------------------+
|
||||||
|
struct Proc {
|
||||||
|
code: Vec<Instr>,
|
||||||
|
args: usize,
|
||||||
|
addr: u64,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Program {
|
pub struct Program {
|
||||||
code: HashMap<u64, Vec<Instr>>
|
code: HashMap<u64, Proc>
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
@ -103,7 +108,7 @@ struct Compiletime<'a> {
|
||||||
stacksize: usize,
|
stacksize: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_term<'a>(term: &VecDeque<Token<'a>>, x: usize, declr: &Vec<Declr<'a>>, ct: &mut Compiletime<'a>, code: &mut Vec<Instr>) {
|
fn parse_term<'a>(term: &VecDeque<Token<'a>>, x: usize, declr: &Vec<Declr<'a>>, ct: &mut Compiletime<'a>, code: &mut Vec<Instr>) -> Result<(), ()>{
|
||||||
for token in term.iter() {
|
for token in term.iter() {
|
||||||
let instr = match token {
|
let instr = match token {
|
||||||
Token::Number(value, hint, _) => {
|
Token::Number(value, hint, _) => {
|
||||||
|
@ -130,13 +135,71 @@ fn parse_term<'a>(term: &VecDeque<Token<'a>>, x: usize, declr: &Vec<Declr<'a>>,
|
||||||
code.push(Instr::Load(*ct.vartable.get(name).unwrap()));
|
code.push(Instr::Load(*ct.vartable.get(name).unwrap()));
|
||||||
ct.stacksize += 1;
|
ct.stacksize += 1;
|
||||||
}
|
}
|
||||||
Token::Operator(op, _, _) => {
|
Token::Operator(op, hint, _) => {
|
||||||
|
|
||||||
code.push(match op {
|
code.push(match op {
|
||||||
crate::token::Operator::Or => Instr::Operation(Operation::Bool(BoolOp::Or)),
|
crate::token::Operator::Or => Instr::Operation(Operation::Bool(BoolOp::Or)),
|
||||||
crate::token::Operator::And => Instr::Operation(Operation::Bool(BoolOp::And)),
|
crate::token::Operator::And => Instr::Operation(Operation::Bool(BoolOp::And)),
|
||||||
crate::token::Operator::Xor => Instr::Operation(Operation::Bool(BoolOp::Xor)),
|
crate::token::Operator::Xor => Instr::Operation(Operation::Bool(BoolOp::Xor)),
|
||||||
|
|
||||||
|
crate::token::Operator::Add => match hint.unwrap() {
|
||||||
|
Prim::Int => Instr::Operation(Operation::Int(IntOp::Add)),
|
||||||
|
Prim::Rat => Instr::Operation(Operation::Rat(RatOp::Add)),
|
||||||
|
_ => panic!()
|
||||||
|
},
|
||||||
|
crate::token::Operator::Sub => match hint.unwrap() {
|
||||||
|
Prim::Int => Instr::Operation(Operation::Int(IntOp::Sub)),
|
||||||
|
Prim::Rat => Instr::Operation(Operation::Rat(RatOp::Sub)),
|
||||||
|
_ => panic!()
|
||||||
|
},
|
||||||
|
crate::token::Operator::Mul => match hint.unwrap() {
|
||||||
|
Prim::Int => Instr::Operation(Operation::Int(IntOp::Mul)),
|
||||||
|
Prim::Rat => Instr::Operation(Operation::Rat(RatOp::Mul)),
|
||||||
|
_ => panic!()
|
||||||
|
},
|
||||||
|
crate::token::Operator::Div => match hint.unwrap() {
|
||||||
|
Prim::Int => Instr::Operation(Operation::Int(IntOp::Div)),
|
||||||
|
Prim::Rat => Instr::Operation(Operation::Rat(RatOp::Div)),
|
||||||
|
_ => panic!()
|
||||||
|
},
|
||||||
|
|
||||||
_ => panic!()
|
crate::token::Operator::Eq => match hint.unwrap() {
|
||||||
|
Prim::Int => Instr::Operation(Operation::Int(IntOp::CmpEq)),
|
||||||
|
Prim::Rat => Instr::Operation(Operation::Rat(RatOp::CmpEq)),
|
||||||
|
Prim::Bool => Instr::Operation(Operation::Bool(BoolOp::CmpEq)),
|
||||||
|
_ => panic!()
|
||||||
|
},
|
||||||
|
crate::token::Operator::NotEq => match hint.unwrap() {
|
||||||
|
Prim::Int => Instr::Operation(Operation::Int(IntOp::CmpNEq)),
|
||||||
|
Prim::Rat => Instr::Operation(Operation::Rat(RatOp::CmpNEq)),
|
||||||
|
Prim::Bool => Instr::Operation(Operation::Bool(BoolOp::CmpNEq)),
|
||||||
|
_ => panic!()
|
||||||
|
},
|
||||||
|
crate::token::Operator::Lt => match hint.unwrap() {
|
||||||
|
Prim::Int => Instr::Operation(Operation::Int(IntOp::CmpLt)),
|
||||||
|
Prim::Rat => Instr::Operation(Operation::Rat(RatOp::CmpLt)),
|
||||||
|
_ => panic!()
|
||||||
|
},
|
||||||
|
crate::token::Operator::Gt => match hint.unwrap() {
|
||||||
|
Prim::Int => Instr::Operation(Operation::Int(IntOp::CmpGt)),
|
||||||
|
Prim::Rat => Instr::Operation(Operation::Rat(RatOp::CmpGt)),
|
||||||
|
_ => panic!()
|
||||||
|
},
|
||||||
|
crate::token::Operator::GtEq => match hint.unwrap() {
|
||||||
|
Prim::Int => Instr::Operation(Operation::Int(IntOp::CmpGtEq)),
|
||||||
|
Prim::Rat => Instr::Operation(Operation::Rat(RatOp::CmpGtEq)),
|
||||||
|
_ => panic!()
|
||||||
|
},
|
||||||
|
crate::token::Operator::LtEq => match hint.unwrap() {
|
||||||
|
Prim::Int => Instr::Operation(Operation::Int(IntOp::CmpLtEq)),
|
||||||
|
Prim::Rat => Instr::Operation(Operation::Rat(RatOp::CmpLtEq)),
|
||||||
|
_ => panic!()
|
||||||
|
},
|
||||||
|
|
||||||
|
crate::token::Operator::Assign => {
|
||||||
|
crate::message(crate::token::MessageType::Critical, format!("Invalid operator: {:?}", op));
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: operatiors
|
// TODO: operatiors
|
||||||
|
@ -161,22 +224,26 @@ fn parse_term<'a>(term: &VecDeque<Token<'a>>, x: usize, declr: &Vec<Declr<'a>>,
|
||||||
_ => ()
|
_ => ()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_block<'a>(block: &VecDeque<Expr<'a>>, x: usize, declr: &Vec<Declr<'a>>, ct: &mut Compiletime<'a>, prog: &mut Vec<Instr>) {
|
fn parse_block<'a>(block: &VecDeque<Expr<'a>>, x: usize, declr: &Vec<Declr<'a>>, ct: &mut Compiletime<'a>, prog: &mut Vec<Instr>) -> Result<(), ()> {
|
||||||
for expr in block.iter() {
|
for expr in block.iter() {
|
||||||
compile_expr(expr, x, declr, ct, prog);
|
compile_expr(expr, x, declr, ct, prog)?;
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile_expr<'a>(expr: &Expr<'a>, x: usize, declr: &Vec<Declr<'a>>, ct: &mut Compiletime<'a>, prog: &mut Vec<Instr>) {
|
fn compile_expr<'a>(expr: &Expr<'a>, x: usize, declr: &Vec<Declr<'a>>, ct: &mut Compiletime<'a>, prog: &mut Vec<Instr>) -> Result<(), ()> {
|
||||||
match expr {
|
match expr {
|
||||||
Expr::Block(block) => parse_block(block, x, declr, ct, prog),
|
Expr::Block(block) => parse_block(block, x, declr, ct, prog)?,
|
||||||
Expr::Term(term) => parse_term(term, x, declr, ct, prog),
|
Expr::Term(term) => parse_term(term, x, declr, ct, prog)?,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile<'a>(funcs: &Vec<Func<'a>>, declrs: &Vec<Declr<'a>>) {
|
pub fn compile<'a>(funcs: &Vec<Func<'a>>, declrs: &Vec<Declr<'a>>) -> Result<Program, ()> {
|
||||||
let mut prog = Program::default();
|
let mut prog = Program::default();
|
||||||
|
|
||||||
for (x, func) in funcs.iter().enumerate() {
|
for (x, func) in funcs.iter().enumerate() {
|
||||||
|
@ -186,10 +253,24 @@ pub fn compile<'a>(funcs: &Vec<Func<'a>>, declrs: &Vec<Declr<'a>>) {
|
||||||
// at beginn the is the return address and the parameter on the stack
|
// at beginn the is the return address and the parameter on the stack
|
||||||
ct.stacksize = declrs[x].args.as_ref().unwrap_or(&vec![]).len() + 1;
|
ct.stacksize = declrs[x].args.as_ref().unwrap_or(&vec![]).len() + 1;
|
||||||
|
|
||||||
compile_expr(func.expr.as_ref().unwrap(), x, declrs, &mut ct, &mut code);
|
compile_expr(func.expr.as_ref().unwrap(), x, declrs, &mut ct, &mut code)?;
|
||||||
|
|
||||||
println!("{:#?}", code);
|
println!("{:#?}", code);
|
||||||
|
|
||||||
prog.code.insert(declrs[x].uuid(), code);
|
prog.code.insert(declrs[x].uuid(), code);
|
||||||
}
|
}
|
||||||
|
Ok(prog)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn execute(prog: &Program) -> Result<i64, ()> {
|
||||||
|
// declaration of entry function
|
||||||
|
let main_fn_declr = crate::parser::data::Declr::main();
|
||||||
|
|
||||||
|
if let Some(main_fn) = prog.code.get(&main_fn_declr.uuid()) {
|
||||||
|
|
||||||
|
Ok(0)
|
||||||
|
} else {
|
||||||
|
crate::message(crate::token::MessageType::Critical, "Program has no main() = int function");
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,18 +3,18 @@ pi:
|
||||||
foo:
|
foo:
|
||||||
Load Int 5
|
Load Int 5
|
||||||
Load Int 6
|
Load Int 6
|
||||||
Add
|
Add Int
|
||||||
Store Int x
|
Store Int x
|
||||||
Load Arg x
|
Load Arg x
|
||||||
Load Int 6
|
Load Int 6
|
||||||
Lt
|
Lt Int
|
||||||
Unless
|
Unless
|
||||||
Load Bool true
|
Load Bool true
|
||||||
Yield
|
Yield
|
||||||
Please
|
Please
|
||||||
Load Arg x
|
Load Arg x
|
||||||
Load Int 6
|
Load Int 6
|
||||||
Lt
|
Lt Int
|
||||||
Unless
|
Unless
|
||||||
Load Bool true
|
Load Bool true
|
||||||
Yield
|
Yield
|
||||||
|
|
Loading…
Reference in New Issue