Skip to content

Commit

Permalink
新增Sym基本类型
Browse files Browse the repository at this point in the history
  • Loading branch information
Bylx666 committed Feb 26, 2024
1 parent 565ad6b commit b359098
Show file tree
Hide file tree
Showing 12 changed files with 221 additions and 56 deletions.
9 changes: 2 additions & 7 deletions samples/helloworld.ks
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@

// 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
}
log(Sym::iter_end())
5 changes: 4 additions & 1 deletion spec/loop.md → spec/for.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@ for(a<200) { // 就是while
a+=1
}

if和for后如果是单语句不是块就会在当前作用域直接执行,包括let和class
if和for后如果是单语句不是块就会在当前作用域直接执行,包括let和class (for v:iter会额外创建一个块)
使用break和continue

迭代器过程中禁止改变迭代器的值
3 changes: 3 additions & 0 deletions spec/sym.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Symbol

Sym类型是为了Key解释器添加新功能所留下的退路, 是基本类型. 目前Sym只有一种:let sym = Sym::iter_end(), 用来在.@next()定义中告知迭代结束.
6 changes: 3 additions & 3 deletions src/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ pub struct NativeMod {
#[derive(Debug, Clone)]
pub struct NativeClassDef {
pub name: Interned,
pub statics: Vec<(Interned, NativeFn)>,
pub methods: Vec<(Interned, NativeMethod)>,
pub getter: Getter,
pub setter: Setter,
pub igetter: IndexGetter,
pub isetter: IndexSetter,
pub onclone: OnClone,
pub ondrop: OnDrop,
pub statics: Vec<(Interned, NativeFn)>,
pub methods: Vec<(Interned, NativeMethod)>
pub ondrop: OnDrop
}

/// 传进main里的东西,作为与原生的接口
Expand Down
Empty file added src/primitive/int.rs
Empty file.
56 changes: 56 additions & 0 deletions src/primitive/iter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use std::cell::UnsafeCell;

use crate::scan::literal::Litr;


pub struct LitrIterator<'a> {
pub v: &'a Litr,
pub n: usize
}
impl<'a> LitrIterator<'a> {
pub fn new(v:&'a Litr)-> Self {
LitrIterator { v, n: 0 }
}
}

impl Iterator for LitrIterator<'_> {
type Item = Litr;
fn next(&mut self) -> Option<Self::Item> {
match self.v {
Litr::Str(s)=>unsafe{s.get_unchecked(self.n..).chars().next().map(|c|{
let s = String::from(c);
self.n += s.len();
Litr::Str(s)}
)}
Litr::Buffer(v)=> {
let v = v.get(self.n).map(|n|Litr::Uint((*n) as usize));
self.n += 1;
v
}
Litr::Uint(n)=> if self.n < *n {
let v = Some(Litr::Uint(self.n));
self.n += 1;
v
}else {None}
Litr::Int(n)=> if (self.n as isize) < *n {
let v = Some(Litr::Int(self.n as isize));
self.n += 1;
v
}else {None}
Litr::List(v)=> {
let v = v.get(self.n).cloned();
self.n += 1;
v
}
Litr::Bool(_)=> panic!("Bool无法迭代"),
Litr::Float(_)=> panic!("Float无法迭代"),
Litr::Func(_)=> panic!("Func无法迭代"),
Litr::Inst(_)=> panic!("Inst?"),
Litr::Ninst(_)=> panic!("Native Inst?"),
Litr::Uninit=> panic!("uninit作为迭代器要判死刑的"),
Litr::Obj(_)=> panic!("Obj是无序的,难以迭代"),
Litr::Sym(_)=> panic!("Sym无法迭代")
}
}
}

6 changes: 5 additions & 1 deletion src/primitive/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ use crate::intern::{Interned, intern};

pub mod std;

pub mod int;
pub mod sym;
pub mod obj;
pub mod iter;

fn getter(_v:*mut NativeInstance, _get:Interned)-> Litr {Litr::Uninit}
fn setter(_v:*mut NativeInstance, _set:Interned, _to:Litr) {}
Expand All @@ -37,7 +40,8 @@ pub fn classes()-> Vec<(Interned, Class)> {unsafe {
cls.iter_mut().map(|(name, f)|(*name, Class::Native(f))).collect()
}else {
let obj_c = new_class(b"Obj", obj::statics());
CLASSES = Some(vec![obj_c]);
let sym_c = new_class(b"Sym", sym::statics());
CLASSES = Some(vec![obj_c, sym_c]);
classes()
}
}}
22 changes: 22 additions & 0 deletions src/primitive/sym.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use crate::{
runtime::calc::CalcRef,
scan::literal::Litr,
intern::{Interned, intern},
native::NativeFn
};

#[derive(Debug, Clone)]
pub enum Symbol {
IterEnd
}


pub fn statics()-> Vec<(Interned, NativeFn)> {
vec![
(intern(b"iter_end"), s_iter_end)
]
}

fn s_iter_end(_:Vec<CalcRef>)-> Litr {
Litr::Sym(Symbol::IterEnd)
}
108 changes: 79 additions & 29 deletions src/runtime/evil.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::primitive;

use super::*;

impl Scope {
Expand Down Expand Up @@ -120,38 +122,49 @@ impl Scope {
}

// 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);
Stmt::ForWhile { condition, exec }=>
start_loop(*self, ||cond(self.calc(condition)), exec),

// for!语句
Stmt::ForLoop(exec)=> start_loop(*self, ||true, exec),

// for v:iter语句
Stmt::ForIter{exec, id, iterator}=> {
use primitive::iter::LitrIterator;
let calced = self.calc_ref(iterator);
let mut scope = self.subscope();
let mut breaked = false;
match &**exec {
Stmt::Block(exec)=> {
for v in LitrIterator::new(&calced) {
if scope.ended || breaked {
outlive::scope_end(scope);
return;
}
scope.vars.clear();
if let Some(id) = id {
scope.vars.push((*id, v));
}
scope.class_uses.clear();
loop_run(scope, &mut breaked, exec)
}
},
_=> for v in LitrIterator::new(&calced) {
if scope.ended {
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);
if let Some(id) = id {
scope.vars.push((*id, v));
}
scope.evil(exec);
}
Stmt::Break=> err!("不允许`for v:iter break`的写法"),
Stmt::Continue=> err!("不允许`for v:iter continue`的写法`"),
}
}
Stmt::ForIter=>(),
Stmt::ForLoop=>(),
scope.ended = true;
outlive::scope_end(scope);
},

Stmt::Match=>(),

Expand All @@ -172,8 +185,42 @@ fn cond(v:Litr)-> bool {
}
}

/// 在一个作用域开始循环
fn start_loop(mut this:Scope, mut condition:impl FnMut()-> bool, exec:&Box<Stmt>) {
// 用重置作用域代替重新创建作用域
if let Stmt::Block(exec) = &**exec {
let mut scope = this.subscope();
let mut breaked = false;
while 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 condition() {
if this.ended {
return;
}
this.evil(exec);
}
}
}
}

/// 以循环模式运行一段语句
fn loop_run(mut scope:Scope,breaked:&mut bool,exec:&Statements) {
// 对于单Stmt的run实现
macro_rules! loop_run_stmt {($stmt:expr)=>{{
match $stmt {
Stmt::Block(exec)=> {
Expand All @@ -182,17 +229,20 @@ fn loop_run(mut scope:Scope,breaked:&mut bool,exec:&Statements) {
s.ended = true;
outlive::scope_end(s);
},
Stmt::Break=> *breaked = true,
Stmt::Break=> return *breaked = true,
Stmt::Continue=> return,
_=> scope.evil($stmt)
};
}}}

for (l, sm) in &exec.0 {
// 如果中途遇到return或者break就停止
if scope.ended || *breaked {
// outlive::scope_end(scope);
return;
}
match sm {
Stmt::Break=> *breaked = true,
Stmt::Break=> return *breaked = true,
Stmt::Continue=> return,
// 把直属该for下的块拦截,检测break和continue
Stmt::Block(v)=> loop_run(scope, breaked, exec),
Stmt::If { condition, exec, els }=> {
Expand Down
3 changes: 2 additions & 1 deletion src/runtime/externer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ pub fn translate(arg:Litr)-> Result<usize,String> {
List(_)=> Err("列表类型不可作为C指针传递".to_string()),
Obj(_)=> Err("Ks对象不可作为C指针传递".to_string()),
Inst(_)=> Err("Ks实例不可作为C指针传递".to_string()),
Ninst(_)=> Err("Ks原生实例不可作为C指针传递".to_string())
Ninst(_)=> Err("Ks原生实例不可作为C指针传递".to_string()),
Sym(_)=> Err("sym不可作为C数字传递".to_string())
}
}

Expand Down
16 changes: 10 additions & 6 deletions src/scan/literal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ pub enum Litr {
List (Vec<Litr>),
Obj (HashMap<Interned, Litr>),
Inst (Instance),
Ninst (NativeInstance)
Ninst (NativeInstance),
Sym (crate::primitive::sym::Symbol)
}
impl Litr {
/// 由Key编译器提供的转字符
Expand Down Expand Up @@ -111,11 +112,14 @@ impl Litr {
s.push_str(" }");
s
}
Ninst(inst)=> {
let mut s = String::new();
s.push_str(&unsafe{&*inst.cls}.name.str());
s.push_str(" { Native }");
s
Ninst(inst)=>
format!("{} {{ Native }}", &unsafe{&*inst.cls}.name.str()),
Sym(s)=> {
use crate::primitive::sym::Symbol;
let t = match s {
Symbol::IterEnd=> "迭代结束"
};
format!("Sym {{ {} }}", t)
}
}
}
Expand Down
43 changes: 35 additions & 8 deletions src/scan/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,16 @@ pub enum Stmt {
exec: Box<Stmt>,
els: Option<Box<Stmt>>
},
ForLoop,
ForLoop(Box<Stmt>),
ForWhile {
condition: Expr,
exec: Box<Stmt>
},
ForIter,
ForIter {
iterator: Expr,
id: Option<Interned>,
exec: Box<Stmt>
},
// If (Statements), // 条件语句
// Loop (Statements), // 循环

Expand Down Expand Up @@ -507,12 +511,35 @@ impl Scanner<'_> {
/// for语句
fn foring(&self)-> Stmt {
self.spaces();
if self.cur() == b'(' {
let condition = self.expr_group();
let exec = Box::new(self.stmt());
Stmt::ForWhile { condition, exec }
}else {
self.err("for语法错误")
match self.cur() {
b'('=> {
let condition = self.expr_group();
let exec = Box::new(self.stmt());
Stmt::ForWhile { condition, exec }
}
b'!'=> {
let exec = Box::new(self.stmt());
Stmt::ForLoop(exec)
}
_=> {
let left = self.literal();
self.spaces();
// 使用迭代器值
if self.cur() == b':' {
self.next();
if let Expr::Variant(id) = left {
let right = self.expr();
let exec = Box::new(self.stmt());
return Stmt::ForIter {iterator:right, id:Some(id), exec};
}
self.err("`for v:iter`语句中:左边必须是标识符")
}

// 不使用迭代器值
let iterator = self.expr_with_left(left);
let exec = Box::new(self.stmt());
Stmt::ForIter {iterator, id:None, exec}
}
}
}
}
Expand Down

0 comments on commit b359098

Please sign in to comment.