Skip to content

Commit

Permalink
Index实现
Browse files Browse the repository at this point in the history
  • Loading branch information
Bylx666 committed Feb 22, 2024
1 parent 8f2110e commit 3773ff3
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 9 deletions.
5 changes: 3 additions & 2 deletions samples/helloworld.ks
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

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

let 😂😂 = 20
log(😂😂)
let o = [2,"s",99]
o[1] = 111
log(o)
12 changes: 11 additions & 1 deletion spec/ops.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,14 @@ Str, Instance, List, Obj也依照以上算法比较。
使用连等:
为了减少无意义的数据复制,目前赋值语句只返回uninit,所以连等并不可用。

一元运算符优先级比二元运算符高
一元运算符优先级比二元运算符高

index[]
以下类型可以使用索引
Buffer 返回Uint,在下标无效时返回uninit
List 返回对应槽位的值
Inst 类实例传入下标可以无视可见性读取第n个属性
Str 获取第i个unicode字符(性能较差,请用迭代器替代)
Uint 传入小于64的数字,返回Bool,代表从右到左的二进制第i位是否为1

index不会报错,在遇到问题时会直接返回uninit
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ fn main()-> ExitCode {
// }));

// index
// 迭代器 loop
// 基本类型的方法,也就是所有litr的prop

// 析构函数..?
Expand Down
67 changes: 64 additions & 3 deletions src/runtime/calc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ impl CalcRef {
CalcRef::Own(v)=> v
}
}
pub fn uninit()-> Self {
CalcRef::Own(Litr::Uninit)
}
}
impl std::ops::Deref for CalcRef {
type Target = Litr;
Expand All @@ -41,10 +44,11 @@ impl Scope {
///
/// 该函数必定发生复制
pub fn calc(&mut self,e:&Expr)-> Litr {
use Litr::*;
match e {
Expr::Call { args, targ }=> self.call(args, targ),

Expr::Index { left, i }=> calc_index(self, left, i).own(),

Expr::Literal(litr)=> litr.clone(),

Expr::Variant(id)=> self.var(*id).clone(),
Expand All @@ -60,6 +64,7 @@ impl Scope {

// 一元运算符
Expr::Unary{right, op}=> {
use Litr::*;
let right = self.calc_ref(right);
match op {
b'-'=> {
Expand Down Expand Up @@ -237,6 +242,7 @@ impl Scope {
let mut from = self.calc_ref(&e);
get_prop(self, &mut *from, *find)
}
Expr::Index { left, i }=> calc_index(self, left, i),
Expr::Variant(id)=> CalcRef::Ref(self.var(*id)),
// todo: Expr::Index
_=> {
Expand Down Expand Up @@ -275,7 +281,10 @@ fn expr_set(this:&mut Scope, left:&Expr, right:Litr) {
let (rf, scope) = this.var_with_scope(*id);
(CalcRef::Ref(rf), scope)
}
// todo: Expr::Index
Expr::Index{left, i}=> {
let (mut from, scope) = calc_ref_with_scope(this, &left);
(calc_index(this, left, i), scope)
}
_=> {
let v = this.calc(e);
// 如果是需要计算的量,就代表其作用域就在this
Expand All @@ -301,7 +310,20 @@ fn expr_set(this:&mut Scope, left:&Expr, right:Litr) {
_=> *get_prop(this, &mut left, *find) = right
}
}
// todo Expr::Index
Expr::Index{left,i}=> {
let (mut left, scope) = calc_ref_with_scope(this, &left);
let i = match this.calc(i) {
Litr::Int(n)=> n as usize,
Litr::Uint(n)=> n,
_=> err!("Index必须是整数")
};
may_add_ref(&right, scope);
if let Litr::Ninst(inst) = &mut *left {
(unsafe{&*inst.cls}.isetter)(inst, i, right)
}else {
*index(left, i) = right;
}
}
_=>{
let (mut left, scope) = calc_ref_with_scope(this, left);
may_add_ref(&right, scope);
Expand Down Expand Up @@ -373,6 +395,45 @@ fn get_prop(this:&Scope, from:&mut Litr, find:Interned)-> CalcRef {
}
}

fn calc_index(this:&mut Scope, left:&Box<Expr>, i:&Box<Expr>)-> CalcRef {
let mut left = this.calc_ref(left);
let i = match this.calc(i) {
Litr::Int(n)=> n as usize,
Litr::Uint(n)=> n,
_=> err!("Index必须是整数")
};
index(left, i)
}
fn index(mut left:CalcRef, i:usize)-> CalcRef {
match &mut *left {
Litr::Buffer(v)=> {
if i>=v.len() {return CalcRef::uninit()}
CalcRef::Own(Litr::Uint(v[i] as usize))
}
Litr::List(v)=> {
if i>=v.len() {return CalcRef::uninit()}
CalcRef::Ref(&mut v[i])
}
Litr::Inst(v)=> {
if i>=v.v.len() {return CalcRef::uninit()}
CalcRef::Ref(&mut v.v[i])
}
Litr::Ninst(v)=> {
CalcRef::Own((unsafe{&*v.cls}.igetter)(v, i))
}
Litr::Str(n)=> {
match n.chars().nth(i) {
Some(c)=> CalcRef::Own(Litr::Str(c.to_string())),
None=> CalcRef::uninit()
}
}
Litr::Uint(n)=> {
if i>=64 {return CalcRef::Own(Litr::Bool(false));}
CalcRef::Own(Litr::Bool((*n & (1<<i)) != 0))
}
_=> CalcRef::uninit()
}
}

fn binary(this:&mut Scope, left:&Box<Expr>, right:&Box<Expr>, op:&Box<[u8]>)-> Litr {
use Litr::*;
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/outlive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,6 @@ pub fn may_add_ref(v:&crate::scan::literal::Litr, target_scope: Scope) {
Litr::Inst(inst)=>
inst.v.iter().for_each(|item|may_add_ref(item, target_scope)),
Litr::Obj(map)=> map.values().for_each(|item|may_add_ref(item, target_scope)),
_=> {}
_=> ()
}
}
24 changes: 22 additions & 2 deletions src/scan/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ pub enum Expr {
args: Vec<Expr>,
targ: Box<Expr>
},
Index{
left: Box<Expr>,
i: Box<Expr>
},
// 创建实例
NewInst{
cls: Interned,
Expand Down Expand Up @@ -139,9 +143,9 @@ impl Scanner<'_> {

// 如果此运算符是括号就代表call
if op == b"(" {
let targ = Box::new(expr_stack.pop().unwrap());
self.next();
self.spaces();
let targ = Box::new(expr_stack.pop().unwrap());
let mut args = Vec::new();
loop {
let e = self.expr();
Expand All @@ -163,7 +167,23 @@ impl Scanner<'_> {
args, targ
});
continue;
};
}

// 如果此运算符是方括号就代表index
if op == b"[" {
self.next();
self.spaces();
let left = Box::new(expr_stack.pop().unwrap());
let i = Box::new(self.expr());
if self.i() >= self.src.len() || self.cur() != b']' {
self.err("未闭合的右括号']'。");
}
self.next();
expr_stack.push(Expr::Index{
left, i
});
continue;
}

// 将新运算符和它右边的值推进栈
self.spaces();
Expand Down

0 comments on commit 3773ff3

Please sign in to comment.