forked from AbleOS/holey-bytes
adding defer
This commit is contained in:
parent
784d552c1d
commit
116f045a5f
3
formatter_only_break_loop.actual
Normal file
3
formatter_only_break_loop.actual
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
inb := fn(f: int): int return f
|
||||||
|
outb := fn(f: int, g: int): void {
|
||||||
|
}
|
3
formatter_only_break_loop.expected
Normal file
3
formatter_only_break_loop.expected
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
inb := fn(f: int): int return f
|
||||||
|
outb := fn(f: int, g: int): void {
|
||||||
|
}
|
|
@ -567,6 +567,23 @@ main := fn(): never {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### defer
|
||||||
|
```hb
|
||||||
|
main := fn(): uint {
|
||||||
|
i := 0
|
||||||
|
loop {
|
||||||
|
defer i += 1
|
||||||
|
|
||||||
|
if i == 10 break
|
||||||
|
|
||||||
|
if i % 3 == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i - 11
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Incomplete Examples
|
### Incomplete Examples
|
||||||
|
|
||||||
#### comptime_pointers
|
#### comptime_pointers
|
||||||
|
|
|
@ -67,8 +67,8 @@ fn token_group(kind: TokenKind) -> TokenGroup {
|
||||||
Decl | Assign | BorAss | XorAss | BandAss | AddAss | SubAss | MulAss | DivAss | ModAss
|
Decl | Assign | BorAss | XorAss | BandAss | AddAss | SubAss | MulAss | DivAss | ModAss
|
||||||
| ShrAss | ShlAss => TG::Assign,
|
| ShrAss | ShlAss => TG::Assign,
|
||||||
DQuote | Quote => TG::String,
|
DQuote | Quote => TG::String,
|
||||||
Slf | Return | If | Else | Loop | Break | Continue | Fn | Idk | Die | Struct | Packed
|
Slf | Defer | Return | If | Else | Loop | Break | Continue | Fn | Idk | Die | Struct
|
||||||
| True | False | Null | Match | Enum => TG::Keyword,
|
| Packed | True | False | Null | Match | Enum => TG::Keyword,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,6 +280,10 @@ impl<'a> Formatter<'a> {
|
||||||
f.write_str("$: ")?;
|
f.write_str("$: ")?;
|
||||||
self.fmt(value, f)
|
self.fmt(value, f)
|
||||||
}
|
}
|
||||||
|
Expr::Defer { value, .. } => {
|
||||||
|
f.write_str("defer ")?;
|
||||||
|
self.fmt(value, f)
|
||||||
|
}
|
||||||
Expr::Slf { .. } => f.write_str("Self"),
|
Expr::Slf { .. } => f.write_str("Self"),
|
||||||
Expr::String { literal, .. } => f.write_str(literal),
|
Expr::String { literal, .. } => f.write_str(literal),
|
||||||
Expr::Comment { literal, .. } => f.write_str(literal),
|
Expr::Comment { literal, .. } => f.write_str(literal),
|
||||||
|
|
|
@ -153,6 +153,7 @@ pub enum TokenKind {
|
||||||
Null,
|
Null,
|
||||||
Idk,
|
Idk,
|
||||||
Die,
|
Die,
|
||||||
|
Defer,
|
||||||
|
|
||||||
// Unused = a-z
|
// Unused = a-z
|
||||||
LBrace = b'{',
|
LBrace = b'{',
|
||||||
|
@ -320,6 +321,7 @@ gen_token_kind! {
|
||||||
Null = b"null",
|
Null = b"null",
|
||||||
Idk = b"idk",
|
Idk = b"idk",
|
||||||
Die = b"die",
|
Die = b"die",
|
||||||
|
Defer = b"defer",
|
||||||
Under = b"_",
|
Under = b"_",
|
||||||
#[punkt]
|
#[punkt]
|
||||||
Ctor = ".{",
|
Ctor = ".{",
|
||||||
|
|
|
@ -303,6 +303,7 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
let mut must_trail = false;
|
let mut must_trail = false;
|
||||||
let mut expr = match token.kind {
|
let mut expr = match token.kind {
|
||||||
T::Ct => E::Ct { pos, value: self.ptr_expr()? },
|
T::Ct => E::Ct { pos, value: self.ptr_expr()? },
|
||||||
|
T::Defer => E::Defer { pos, value: self.ptr_expr()? },
|
||||||
T::Slf => E::Slf { pos },
|
T::Slf => E::Slf { pos },
|
||||||
T::Directive if self.lexer.slice(token.range()) == "use" => {
|
T::Directive if self.lexer.slice(token.range()) == "use" => {
|
||||||
self.expect_advance(TokenKind::LParen)?;
|
self.expect_advance(TokenKind::LParen)?;
|
||||||
|
@ -850,6 +851,11 @@ generate_expr! {
|
||||||
pos: Pos,
|
pos: Pos,
|
||||||
value: &'a Self,
|
value: &'a Self,
|
||||||
},
|
},
|
||||||
|
/// `'defer' Expr`
|
||||||
|
Defer {
|
||||||
|
pos: Pos,
|
||||||
|
value: &'a Self,
|
||||||
|
},
|
||||||
/// `'Self'`
|
/// `'Self'`
|
||||||
Slf {
|
Slf {
|
||||||
pos: Pos,
|
pos: Pos,
|
||||||
|
|
102
lang/src/son.rs
102
lang/src/son.rs
|
@ -27,7 +27,6 @@ use {
|
||||||
},
|
},
|
||||||
hashbrown::hash_map,
|
hashbrown::hash_map,
|
||||||
hbbytecode::DisasmError,
|
hbbytecode::DisasmError,
|
||||||
std::panic,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const VOID: Nid = 0;
|
const VOID: Nid = 0;
|
||||||
|
@ -2165,6 +2164,7 @@ struct Loop {
|
||||||
ctrl: [StrongRef; 2],
|
ctrl: [StrongRef; 2],
|
||||||
ctrl_scope: [Scope; 2],
|
ctrl_scope: [Scope; 2],
|
||||||
scope: Scope,
|
scope: Scope,
|
||||||
|
defer_base: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
mod strong_ref {
|
mod strong_ref {
|
||||||
|
@ -2350,22 +2350,26 @@ pub struct ItemCtx {
|
||||||
inline_var_base: usize,
|
inline_var_base: usize,
|
||||||
inline_aclass_base: usize,
|
inline_aclass_base: usize,
|
||||||
inline_depth: u16,
|
inline_depth: u16,
|
||||||
|
inline_defer_base: usize,
|
||||||
inline_ret: Option<(Value, StrongRef, Scope, Option<AClass>)>,
|
inline_ret: Option<(Value, StrongRef, Scope, Option<AClass>)>,
|
||||||
nodes: Nodes,
|
nodes: Nodes,
|
||||||
ctrl: StrongRef,
|
ctrl: StrongRef,
|
||||||
loops: Vec<Loop>,
|
loops: Vec<Loop>,
|
||||||
|
defers: Vec<(Pos, ExprRef)>,
|
||||||
scope: Scope,
|
scope: Scope,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ItemCtx {
|
impl ItemCtx {
|
||||||
fn init(&mut self, file: Module, parent: ty::Id, ret: Option<ty::Id>, task_base: usize) {
|
fn init(&mut self, file: Module, parent: ty::Id, ret: Option<ty::Id>, task_base: usize) {
|
||||||
debug_assert_eq!(self.loops.len(), 0);
|
debug_assert_eq!(self.loops.len(), 0);
|
||||||
|
debug_assert_eq!(self.defers.len(), 0);
|
||||||
debug_assert_eq!(self.scope.vars.len(), 0);
|
debug_assert_eq!(self.scope.vars.len(), 0);
|
||||||
debug_assert_eq!(self.scope.aclasses.len(), 0);
|
debug_assert_eq!(self.scope.aclasses.len(), 0);
|
||||||
debug_assert!(self.inline_ret.is_none());
|
debug_assert!(self.inline_ret.is_none());
|
||||||
debug_assert_eq!(self.inline_depth, 0);
|
debug_assert_eq!(self.inline_depth, 0);
|
||||||
debug_assert_eq!(self.inline_var_base, 0);
|
debug_assert_eq!(self.inline_var_base, 0);
|
||||||
debug_assert_eq!(self.inline_aclass_base, 0);
|
debug_assert_eq!(self.inline_aclass_base, 0);
|
||||||
|
debug_assert_eq!(self.inline_defer_base, 0);
|
||||||
|
|
||||||
self.file = file;
|
self.file = file;
|
||||||
self.parent = parent;
|
self.parent = parent;
|
||||||
|
@ -2858,6 +2862,10 @@ impl<'a> Codegen<'a> {
|
||||||
self.ci.nodes[global].aclass = GLOBAL_ACLASS as _;
|
self.ci.nodes[global].aclass = GLOBAL_ACLASS as _;
|
||||||
Some(Value::new(global).ty(ty))
|
Some(Value::new(global).ty(ty))
|
||||||
}
|
}
|
||||||
|
Expr::Defer { pos, value } => {
|
||||||
|
self.ci.defers.push((pos, ExprRef::new(value)));
|
||||||
|
Some(Value::VOID)
|
||||||
|
}
|
||||||
Expr::Return { pos, val } => {
|
Expr::Return { pos, val } => {
|
||||||
let mut value = if let Some(val) = val {
|
let mut value = if let Some(val) = val {
|
||||||
self.raw_expr_ctx(val, Ctx { ty: self.ci.ret })?
|
self.raw_expr_ctx(val, Ctx { ty: self.ci.ret })?
|
||||||
|
@ -2868,9 +2876,10 @@ impl<'a> Codegen<'a> {
|
||||||
|
|
||||||
let expected = *self.ci.ret.get_or_insert(value.ty);
|
let expected = *self.ci.ret.get_or_insert(value.ty);
|
||||||
self.assert_ty(pos, &mut value, expected, "return value");
|
self.assert_ty(pos, &mut value, expected, "return value");
|
||||||
|
self.strip_ptr(&mut value);
|
||||||
|
self.gen_defers(self.ci.inline_defer_base);
|
||||||
|
|
||||||
if self.ci.inline_depth == 0 {
|
if self.ci.inline_depth == 0 {
|
||||||
self.strip_ptr(&mut value);
|
|
||||||
debug_assert_ne!(self.ci.ctrl.get(), VOID);
|
debug_assert_ne!(self.ci.ctrl.get(), VOID);
|
||||||
let mut inps = Vc::from([self.ci.ctrl.get(), value.id]);
|
let mut inps = Vc::from([self.ci.ctrl.get(), value.id]);
|
||||||
for (i, aclass) in self.ci.scope.aclasses.iter_mut().enumerate() {
|
for (i, aclass) in self.ci.scope.aclasses.iter_mut().enumerate() {
|
||||||
|
@ -2888,7 +2897,16 @@ impl<'a> Codegen<'a> {
|
||||||
self.ci.ctrl.set(NEVER, &mut self.ci.nodes);
|
self.ci.ctrl.set(NEVER, &mut self.ci.nodes);
|
||||||
self.ci.nodes[ret].pos = pos;
|
self.ci.nodes[ret].pos = pos;
|
||||||
self.ci.nodes.bind(ret, NEVER);
|
self.ci.nodes.bind(ret, NEVER);
|
||||||
} else if let Some((pv, ctrl, scope, aclass)) = &mut self.ci.inline_ret {
|
} else if let Some((mut pv, mut ctrl, mut scope, aclass)) =
|
||||||
|
self.ci.inline_ret.take()
|
||||||
|
{
|
||||||
|
if value.ty.loc(self.tys) == Loc::Stack {
|
||||||
|
let stck = self.new_stack(pos, value.ty);
|
||||||
|
self.store_mem(stck, value.ty, value.id);
|
||||||
|
value.id = stck;
|
||||||
|
value.ptr = true;
|
||||||
|
}
|
||||||
|
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
aclass.is_none(),
|
aclass.is_none(),
|
||||||
"TODO: oh no, we cant return structs from divergent branches"
|
"TODO: oh no, we cant return structs from divergent branches"
|
||||||
|
@ -2904,8 +2922,8 @@ impl<'a> Codegen<'a> {
|
||||||
);
|
);
|
||||||
self.ci.nodes.merge_scopes(
|
self.ci.nodes.merge_scopes(
|
||||||
&mut self.ci.loops,
|
&mut self.ci.loops,
|
||||||
ctrl,
|
&ctrl,
|
||||||
scope,
|
&mut scope,
|
||||||
&mut self.ci.scope,
|
&mut self.ci.scope,
|
||||||
self.tys,
|
self.tys,
|
||||||
);
|
);
|
||||||
|
@ -2918,7 +2936,15 @@ impl<'a> Codegen<'a> {
|
||||||
);
|
);
|
||||||
self.ci.nodes.lock(pv.id);
|
self.ci.nodes.lock(pv.id);
|
||||||
self.ci.ctrl.set(NEVER, &mut self.ci.nodes);
|
self.ci.ctrl.set(NEVER, &mut self.ci.nodes);
|
||||||
|
self.ci.inline_ret = Some((pv, ctrl, scope, aclass));
|
||||||
} else {
|
} else {
|
||||||
|
if value.ty.loc(self.tys) == Loc::Stack {
|
||||||
|
let stck = self.new_stack(pos, value.ty);
|
||||||
|
self.store_mem(stck, value.ty, value.id);
|
||||||
|
value.id = stck;
|
||||||
|
value.ptr = true;
|
||||||
|
}
|
||||||
|
|
||||||
for (i, aclass) in self.ci.scope.aclasses[..2].iter_mut().enumerate() {
|
for (i, aclass) in self.ci.scope.aclasses[..2].iter_mut().enumerate() {
|
||||||
self.ci.nodes.load_loop_aclass(i, aclass, &mut self.ci.loops);
|
self.ci.nodes.load_loop_aclass(i, aclass, &mut self.ci.loops);
|
||||||
}
|
}
|
||||||
|
@ -3632,6 +3658,7 @@ impl<'a> Codegen<'a> {
|
||||||
Expr::Block { stmts, .. } => {
|
Expr::Block { stmts, .. } => {
|
||||||
let base = self.ci.scope.vars.len();
|
let base = self.ci.scope.vars.len();
|
||||||
let aclass_base = self.ci.scope.aclasses.len();
|
let aclass_base = self.ci.scope.aclasses.len();
|
||||||
|
let defer_base = self.ci.defers.len();
|
||||||
|
|
||||||
let mut ret = Some(Value::VOID);
|
let mut ret = Some(Value::VOID);
|
||||||
for stmt in stmts {
|
for stmt in stmts {
|
||||||
|
@ -3662,6 +3689,9 @@ impl<'a> Codegen<'a> {
|
||||||
aclass.remove(&mut self.ci.nodes);
|
aclass.remove(&mut self.ci.nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.gen_defers(defer_base);
|
||||||
|
self.ci.defers.truncate(defer_base);
|
||||||
|
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
Expr::Loop { body, .. } => {
|
Expr::Loop { body, .. } => {
|
||||||
|
@ -3680,6 +3710,7 @@ impl<'a> Codegen<'a> {
|
||||||
ctrl: [StrongRef::DEFAULT; 2],
|
ctrl: [StrongRef::DEFAULT; 2],
|
||||||
ctrl_scope: core::array::from_fn(|_| Default::default()),
|
ctrl_scope: core::array::from_fn(|_| Default::default()),
|
||||||
scope: self.ci.scope.dup(&mut self.ci.nodes),
|
scope: self.ci.scope.dup(&mut self.ci.nodes),
|
||||||
|
defer_base: self.ci.defers.len(),
|
||||||
});
|
});
|
||||||
|
|
||||||
for var in self.ci.scope.vars.iter_mut().skip(self.ci.inline_var_base) {
|
for var in self.ci.scope.vars.iter_mut().skip(self.ci.inline_var_base) {
|
||||||
|
@ -3721,8 +3752,16 @@ impl<'a> Codegen<'a> {
|
||||||
cons.clear(&mut self.ci.nodes);
|
cons.clear(&mut self.ci.nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
let Loop { node, ctrl: [.., bre], ctrl_scope: [.., mut bres], mut scope } =
|
let Loop {
|
||||||
self.ci.loops.pop().unwrap();
|
node,
|
||||||
|
ctrl: [.., bre],
|
||||||
|
ctrl_scope: [.., mut bres],
|
||||||
|
mut scope,
|
||||||
|
defer_base,
|
||||||
|
} = self.ci.loops.pop().unwrap();
|
||||||
|
|
||||||
|
self.gen_defers(defer_base);
|
||||||
|
self.ci.defers.truncate(defer_base);
|
||||||
|
|
||||||
self.ci.nodes.modify_input(node, 1, self.ci.ctrl.get());
|
self.ci.nodes.modify_input(node, 1, self.ci.ctrl.get());
|
||||||
|
|
||||||
|
@ -4038,7 +4077,15 @@ impl<'a> Codegen<'a> {
|
||||||
Some(Value::VOID)
|
Some(Value::VOID)
|
||||||
}
|
}
|
||||||
ref e => {
|
ref e => {
|
||||||
let ty = self.ty(e);
|
let ty = self.parse_ty(
|
||||||
|
TyScope {
|
||||||
|
file: self.ci.file,
|
||||||
|
parent: self.ci.parent,
|
||||||
|
name: None,
|
||||||
|
alloc_const: false,
|
||||||
|
},
|
||||||
|
e,
|
||||||
|
);
|
||||||
Some(self.ci.nodes.new_const_lit(ty::Id::TYPE, ty))
|
Some(self.ci.nodes.new_const_lit(ty::Id::TYPE, ty))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4326,6 +4373,8 @@ impl<'a> Codegen<'a> {
|
||||||
|
|
||||||
let prev_var_base = mem::replace(&mut self.ci.inline_var_base, var_base);
|
let prev_var_base = mem::replace(&mut self.ci.inline_var_base, var_base);
|
||||||
let prev_aclass_base = mem::replace(&mut self.ci.inline_aclass_base, aclass_base);
|
let prev_aclass_base = mem::replace(&mut self.ci.inline_aclass_base, aclass_base);
|
||||||
|
let prev_defer_base =
|
||||||
|
mem::replace(&mut self.ci.inline_defer_base, self.ci.defers.len());
|
||||||
let prev_inline_ret = self.ci.inline_ret.take();
|
let prev_inline_ret = self.ci.inline_ret.take();
|
||||||
self.ci.inline_depth += 1;
|
self.ci.inline_depth += 1;
|
||||||
let prev_ret = self.ci.ret.replace(sig.ret);
|
let prev_ret = self.ci.ret.replace(sig.ret);
|
||||||
|
@ -4351,6 +4400,7 @@ impl<'a> Codegen<'a> {
|
||||||
self.ci.inline_depth -= 1;
|
self.ci.inline_depth -= 1;
|
||||||
self.ci.inline_var_base = prev_var_base;
|
self.ci.inline_var_base = prev_var_base;
|
||||||
self.ci.inline_aclass_base = prev_aclass_base;
|
self.ci.inline_aclass_base = prev_aclass_base;
|
||||||
|
self.ci.inline_defer_base = prev_defer_base;
|
||||||
for var in self.ci.scope.vars.drain(var_base..) {
|
for var in self.ci.scope.vars.drain(var_base..) {
|
||||||
var.remove(&mut self.ci.nodes);
|
var.remove(&mut self.ci.nodes);
|
||||||
}
|
}
|
||||||
|
@ -4755,12 +4805,25 @@ impl<'a> Codegen<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn gen_defers(&mut self, base: usize) -> Option<()> {
|
||||||
|
let defers = mem::take(&mut self.ci.defers);
|
||||||
|
for &(_, defer) in defers.iter().skip(base).rev() {
|
||||||
|
self.expr(defer.get(self.file()))?;
|
||||||
|
}
|
||||||
|
self.ci.defers = defers;
|
||||||
|
Some(())
|
||||||
|
}
|
||||||
|
|
||||||
fn jump_to(&mut self, pos: Pos, id: usize) -> Option<Value> {
|
fn jump_to(&mut self, pos: Pos, id: usize) -> Option<Value> {
|
||||||
let Some(mut loob) = self.ci.loops.last_mut() else {
|
let Some(&mut Loop { defer_base, .. }) = self.ci.loops.last_mut() else {
|
||||||
self.error(pos, "break outside a loop");
|
self.error(pos, "break outside a loop");
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.gen_defers(defer_base)?;
|
||||||
|
|
||||||
|
let mut loob = self.ci.loops.last_mut().unwrap();
|
||||||
|
|
||||||
if loob.ctrl[id].is_live() {
|
if loob.ctrl[id].is_live() {
|
||||||
loob.ctrl[id].set(
|
loob.ctrl[id].set(
|
||||||
self.ci.nodes.new_node(
|
self.ci.nodes.new_node(
|
||||||
|
@ -4985,7 +5048,7 @@ impl<'a> Codegen<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ty_in(&mut self, file: Module, parent: ty::Id, expr: &Expr) -> ty::Id {
|
fn ty_in(&mut self, file: Module, parent: ty::Id, expr: &Expr) -> ty::Id {
|
||||||
self.parse_ty(TyScope { file, parent, name: None }, expr)
|
self.parse_ty(TyScope { file, parent, name: None, alloc_const: true }, expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ty_display(&self, ty: ty::Id) -> ty::Display {
|
fn ty_display(&self, ty: ty::Id) -> ty::Display {
|
||||||
|
@ -5422,7 +5485,10 @@ impl<'a> Codegen<'a> {
|
||||||
.push(Const { ast: ExprRef::new(expr), name, file, parent })
|
.push(Const { ast: ExprRef::new(expr), name, file, parent })
|
||||||
.into()
|
.into()
|
||||||
} else {
|
} else {
|
||||||
self.parse_ty(TyScope { file, parent, name: Some(name) }, right)
|
self.parse_ty(
|
||||||
|
TyScope { file, parent, name: Some(name), alloc_const: true },
|
||||||
|
right,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -5599,8 +5665,16 @@ impl<'a> Codegen<'a> {
|
||||||
|
|
||||||
self.tys.ins.funcs.push(func).into()
|
self.tys.ins.funcs.push(func).into()
|
||||||
}
|
}
|
||||||
_ if let Some(name) = sc.name => self.eval_global(sc.file, name, expr),
|
_ if sc.alloc_const
|
||||||
_ => ty::Id::from(self.eval_const(sc.file, expr, ty::Id::TYPE)),
|
&& let Some(name) = sc.name =>
|
||||||
|
{
|
||||||
|
self.eval_global(sc.file, name, expr)
|
||||||
|
}
|
||||||
|
_ if sc.alloc_const => ty::Id::from(self.eval_const(sc.file, expr, ty::Id::TYPE)),
|
||||||
|
ref e => {
|
||||||
|
self.error_unhandled_ast(e, "bruh");
|
||||||
|
ty::Id::NEVER
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5610,6 +5684,7 @@ struct TyScope {
|
||||||
file: Module,
|
file: Module,
|
||||||
parent: ty::Id,
|
parent: ty::Id,
|
||||||
name: Option<Ident>,
|
name: Option<Ident>,
|
||||||
|
alloc_const: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TyScope {
|
impl TyScope {
|
||||||
|
@ -5688,6 +5763,7 @@ mod tests {
|
||||||
idk;
|
idk;
|
||||||
generic_functions;
|
generic_functions;
|
||||||
die;
|
die;
|
||||||
|
defer;
|
||||||
|
|
||||||
// Incomplete Examples;
|
// Incomplete Examples;
|
||||||
//comptime_pointers;
|
//comptime_pointers;
|
||||||
|
|
19
lang/tests/son_tests_defer.txt
Normal file
19
lang/tests/son_tests_defer.txt
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
main:
|
||||||
|
LI64 r15, 3d
|
||||||
|
LI64 r16, 10d
|
||||||
|
CP r14, r0
|
||||||
|
CP r13, r14
|
||||||
|
3: JNE r13, r16, :0
|
||||||
|
LI64 r14, -10d
|
||||||
|
ADD64 r14, r13, r14
|
||||||
|
CP r1, r14
|
||||||
|
JMP :1
|
||||||
|
0: DIRU64 r0, r17, r13, r15
|
||||||
|
JNE r17, r14, :2
|
||||||
|
JMP :2
|
||||||
|
2: ADDI64 r13, r13, 1d
|
||||||
|
JMP :3
|
||||||
|
1: JALA r0, r31, 0a
|
||||||
|
code size: 103
|
||||||
|
ret: 0
|
||||||
|
status: Ok(())
|
|
@ -1,6 +1,19 @@
|
||||||
main:
|
main:
|
||||||
CP r1, r0
|
ADDI64 r254, r254, -72d
|
||||||
|
ADDI64 r13, r254, 24d
|
||||||
|
ST r0, r254, 24a, 8h
|
||||||
|
LI64 r14, 1d
|
||||||
|
ST r14, r254, 32a, 8h
|
||||||
|
LI64 r14, 2d
|
||||||
|
ST r14, r254, 40a, 8h
|
||||||
|
ADDI64 r14, r254, 0d
|
||||||
|
BMC r13, r14, 24h
|
||||||
|
ADDI64 r13, r254, 48d
|
||||||
|
BMC r14, r13, 24h
|
||||||
|
LD r13, r254, 48a, 8h
|
||||||
|
CP r1, r13
|
||||||
|
ADDI64 r254, r254, 72d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 22
|
code size: 159
|
||||||
ret: 0
|
ret: 0
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
Loading…
Reference in a new issue