Skip to content

Commit

Permalink
if 和while实现
Browse files Browse the repository at this point in the history
  • Loading branch information
Bylx666 committed Feb 25, 2024
1 parent a92bb4b commit 565ad6b
Show file tree
Hide file tree
Showing 13 changed files with 232 additions and 109 deletions.
8 changes: 7 additions & 1 deletion samples/helloworld.ks
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@

mod D:\code\rs\key-native\target\debug\key_native.dll> m
// mod D:\code\rs\key-native\target\debug\key_native.dll> m

let a=0
for(a<5) {
a+=1;
log(a)
if a>3 break
}
2 changes: 1 addition & 1 deletion spec/classes.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
## 定义结构

逗号可以省略
首字母必须大写
首字母建议大写
```
class MyClass {
a
Expand Down
4 changes: 2 additions & 2 deletions spec/declare.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ let buf = 'Genshin{0F20}'; // Buffer(u8 {}内允许空格换行)
## 注释
```
// 单行注释
/`
/'
多行注释
多行注释
`/
'/
```
多行注释的结尾``/`省略的话就可以自动注释到文件结尾。

Expand Down
13 changes: 6 additions & 7 deletions spec/loop.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@

loop(20) {

}
loop {

for 200 {} // 循环200次(本质上是把200变成一个200次的迭代器)
for a: 200 {} // 循环200次并以a作为迭代器过程的值
for!{} // 无限循环
for(a<200) { // 就是while
a+=1
}
loop (let? i<50) {

}
if和for后如果是单语句不是块就会在当前作用域直接执行,包括let和class
3 changes: 2 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ fn main()-> ExitCode {
// }
// }));

// 把return_to也做一个run的版本
// 迭代器 loop
// 基本类型的方法,也就是所有litr的prop

Expand Down Expand Up @@ -60,7 +61,7 @@ fn main()-> ExitCode {

intern::init();
let scanned = scan::scan(fs::read("D:\\code\\rs\\key-lang\\samples\\helloworld.ks").unwrap());
// println!("{scanned:?}");
println!("{scanned:?}");
let exit = runtime::run(&scanned);
if let scan::literal::Litr::Int(code) = exit.returned {
return ExitCode::from(code as u8);
Expand Down
6 changes: 3 additions & 3 deletions src/runtime/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,17 @@ impl Scope {
let kself = if let Some(s) = f.bound {s}else {self.kself};

let mut ret = Litr::Uninit;
let mut return_to = Some(&mut ret as *mut Litr);
let mut scope = Scope::new(ScopeInner {
parent:Some(f.scope),
return_to:&mut return_to,
return_to:&mut ret,
class_defs:Vec::new(),
class_uses:Vec::new(),
kself,
vars,
imports: self.imports,
exports: self.exports,
outlives: Outlives::new()
outlives: Outlives::new(),
ended: false
});
scope.run(&f.stmts);
ret
Expand Down
127 changes: 111 additions & 16 deletions src/runtime/evil.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,7 @@ impl Scope {
self.vars.push((a.id, v));
}
// 块语句
Stmt::Block(s)=> {
let mut scope = Scope::new(ScopeInner {
parent:Some(*self),
return_to: self.return_to,
class_defs:Vec::new(),
class_uses:Vec::new(),
kself: self.kself,
vars: Vec::with_capacity(16),
imports: self.imports,
exports: self.exports,
outlives: Outlives::new()
});
scope.run(s);
}
Stmt::Block(s)=> self.subscope().run(s),

// 类型声明
Stmt::Class(raw)=> {
Expand Down Expand Up @@ -109,8 +96,116 @@ impl Scope {
module.classes.push((raw.name,ptr))
}

Stmt::Return(_)=> err!("return语句不应被直接evil"),
_=> {}
// 返回一个值
Stmt::Return(expr)=> {
// 遇到return语句就停止当前遍历
// 并将返回值指针相同(在同一函数内的作用域)设为已结束
unsafe{*self.return_to = self.calc(expr)};
self.ended = true;
let mut scope = *self;
while let Some(mut s) = scope.parent {
if s.return_to != self.return_to {break;}
s.ended = true;
scope = s;
}
},

// if else
Stmt::If { condition, exec, els }=> {
if cond(self.calc(condition)) {
self.evil(exec)
}else if let Some(els) = els {
self.evil(els)
}
}

// for ()语句
Stmt::ForWhile { condition, exec }=> {
// 用重置作用域代替重新创建作用域
if let Stmt::Block(exec) = &**exec {
let mut scope = self.subscope();
let mut breaked = false;
while cond(self.calc(condition)) {
if scope.ended || breaked {
outlive::scope_end(scope);
return;
}
scope.vars.clear();
scope.class_uses.clear();
loop_run(scope, &mut breaked, exec);
}
scope.ended = true;
outlive::scope_end(scope);
// 单语句将由当前作用域代为执行,不再创建新作用域
}else {
match &**exec {
Stmt::Break=> err!("不允许`for() break`的写法"),
Stmt::Continue=> err!("不允许`for() continue`的写法`"),
_=> while cond(self.calc(condition)) {
if self.ended {
return;
}
self.evil(exec);
}
}
}
}
Stmt::ForIter=>(),
Stmt::ForLoop=>(),

Stmt::Match=>(),

// -
Stmt::Break=> err!("break不在循环体内"),
Stmt::Continue=> err!("continue不在循环体内"),
Stmt::Empty=> (),
}
}
}

/// 判断if后的条件
fn cond(v:Litr)-> bool {
match v {
Litr::Bool(b)=> b,
Litr::Uninit=> false,
_=> err!("条件必须为Bool或uninit")
}
}

/// 以循环模式运行一段语句
fn loop_run(mut scope:Scope,breaked:&mut bool,exec:&Statements) {
macro_rules! loop_run_stmt {($stmt:expr)=>{{
match $stmt {
Stmt::Block(exec)=> {
let mut s = scope.subscope();
loop_run(s, breaked, exec);
s.ended = true;
outlive::scope_end(s);
},
Stmt::Break=> *breaked = true,
_=> scope.evil($stmt)
};
}}}
for (l, sm) in &exec.0 {
if scope.ended || *breaked {
// outlive::scope_end(scope);
return;
}
match sm {
Stmt::Break=> *breaked = true,
// 把直属该for下的块拦截,检测break和continue
Stmt::Block(v)=> loop_run(scope, breaked, exec),
Stmt::If { condition, exec, els }=> {
if cond(scope.calc(condition)) {
loop_run_stmt!(&**exec)
}else if let Some(els) = els {
loop_run_stmt!(&**els)
}
},
_=> {
unsafe{LINE = *l;}
scope.evil(sm);
}
}
}
}
1 change: 0 additions & 1 deletion src/runtime/externer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use crate::c::{dlopen,dlsym};
use crate::scan::literal::{
Litr, LocalFunc
};
use crate::runtime::ScopeInner;

static mut EXEC:Option<LocalFunc> = None;

Expand Down
78 changes: 43 additions & 35 deletions src/runtime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ pub enum Class {
pub struct ScopeInner {
/// 父作用域
pub parent: Option<Scope>,
/// 返回值指针,None代表已返回
pub return_to: *mut Option<*mut Litr>,
/// 返回值指针
pub return_to: *mut Litr,
/// (变量名,值)
pub vars: Vec<(Interned, Litr)>,
/// 类型声明(和作用域生命周期一致)
Expand All @@ -66,7 +66,10 @@ pub struct ScopeInner {
/// ks本身作为模块导出的指针
pub exports: *mut LocalMod,
/// 该作用域生命周期会被outlive的函数延长
pub outlives: outlive::Outlives
pub outlives: outlive::Outlives,
/// 遇到return时会提前变为true
/// 用于标识return. break有自己的判断方法
pub ended: bool
}


Expand All @@ -79,12 +82,25 @@ pub struct ScopeInner {
pub struct Scope {
pub ptr:*mut ScopeInner
}
impl std::ops::Deref for Scope {
type Target = ScopeInner;
fn deref(&self) -> &Self::Target {
unsafe {&*self.ptr}
}
}
impl std::ops::DerefMut for Scope {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe {&mut *self.ptr}
}
}

impl Scope {
pub fn new(s:ScopeInner)-> Self {
Scope {
ptr: Box::into_raw(Box::new(s))
}
}

/// 确认此作用域是否为一个作用域的子作用域
pub fn subscope_of(&self,upper:Scope)-> bool {
let mut scope = *self;
Expand All @@ -100,47 +116,39 @@ impl Scope {
}
false
}
}
impl std::ops::Deref for Scope {
type Target = ScopeInner;
fn deref(&self) -> &Self::Target {
unsafe {&*self.ptr}
}
}
impl std::ops::DerefMut for Scope {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe {&mut *self.ptr}

/// 生成一个子作用域
pub fn subscope(&self)-> Scope {
Scope::new(ScopeInner {
parent:Some(*self),
return_to: self.return_to,
class_defs:Vec::new(),
class_uses:Vec::new(),
kself: self.kself,
vars: Vec::with_capacity(16),
imports: self.imports,
exports: self.exports,
outlives: Outlives::new(),
ended: false
})
}
}

impl Scope {
/// 在此作用域运行ast代码
///
/// 此行为会根据引用计数回收作用域,在run之后再次使用Scope是未定义行为
pub fn run(mut self, codes:&Statements) {
for (l, sm) in &codes.0 {
// 运行一行语句
unsafe{LINE = *l;}
self.evil(sm);

// 如果子作用域返回过了,这里就会是None状态
let return_to = unsafe{&*self.return_to};
if let None = return_to {
return;
}

// 遇到return语句就停止当前遍历
if let Stmt::Return(expr) = sm {
unsafe {
if let Some(p) = return_to {
**p = self.calc(expr);
}
*self.return_to = None;
}
// 停止已结束的作用域
if self.ended {
outlive::scope_end(self);
return;
}

self.evil(sm);
}
self.ended = true;
outlive::scope_end(self);
}

Expand Down Expand Up @@ -249,18 +257,17 @@ pub struct RunResult {
/// 创建顶级作用域并运行一段程序
pub fn run(s:&Statements)-> RunResult {
let mut top_ret = Litr::Uint(0);
let mut return_to = &mut Some(&mut top_ret as *mut Litr);
let mut imports = Vec::new();
let mut exports = LocalMod { name: intern(b"mod"), funcs: Vec::new(), classes: Vec::new() };
let mut kself = Litr::Uninit;
top_scope(return_to, &mut imports, &mut exports,&mut kself).run(s);
top_scope(&mut top_ret, &mut imports, &mut exports,&mut kself).run(s);
RunResult { returned: top_ret, exports, kself }
}

/// 创建顶级作用域
///
/// 自定义此函数可添加初始函数和变量
pub fn top_scope(return_to:*mut Option<*mut Litr>, imports:*mut Vec<Module>, exports:*mut LocalMod, kself:*mut Litr)-> Scope {
pub fn top_scope(return_to:*mut Litr, imports:*mut Vec<Module>, exports:*mut LocalMod, kself:*mut Litr)-> Scope {
let mut vars = Vec::<(Interned, Litr)>::with_capacity(16);
vars.push((intern(b"log"),
Litr::Func(Function::Native(crate::primitive::std::log)))
Expand All @@ -276,6 +283,7 @@ pub fn top_scope(return_to:*mut Option<*mut Litr>, imports:*mut Vec<Module>, exp
imports,
exports,
vars,
outlives: Outlives::new()
outlives: Outlives::new(),
ended: false
})
}
Loading

0 comments on commit 565ad6b

Please sign in to comment.