Skip to content

Commit

Permalink
更深的赋值实现和其outlive算法实现
Browse files Browse the repository at this point in the history
  • Loading branch information
Bylx666 committed Feb 15, 2024
1 parent 4fb21e8 commit d46a5da
Show file tree
Hide file tree
Showing 15 changed files with 350 additions and 293 deletions.
23 changes: 19 additions & 4 deletions samples/helloworld.ks
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@

mod D:\code\rs\key-lang\samples\testmod.ks> mym
let s = mym-:MyStruct::new();
class A {
a b
new():A{
a:A{b:9}
},
.f() {
self.a = 99;
:self
}
.g() {
log(self.a)
}
}

class A = mym-:MyStruct
log(A::new().b)
let a = A::new();
{
let f() log("ok")
a.a.b = f
}
a.a.b()
4 changes: 1 addition & 3 deletions samples/testmod.ks
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@
a,>b
>.d(){log("ok");:8}
>new():MyStruct {
a:99
b:22
b:MyStruct {b:20}
}
}
let s = MyStruct::new()
}
20 changes: 8 additions & 12 deletions spec/ops.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,27 +23,23 @@ uninit的逻辑(&&||)和false行为相同
比较数字时会将整数统一为Int
浮点数和整数会统一为浮点数

buffer比较依赖Rust底层实现,源码如下
buffer比较依赖以下算法,以==为例的源码如下。其他比较运算符可直接原地替换==得到正确的结果。
```rust
fn compare(left: &[u8], right: &[u8]) -> Ordering {
fn compare(left: &[u8], right: &[u8]) -> bool {
// 首先将短的buffer长度作为比较对象
let l = core::cmp::min(left.len(), right.len());
// 使用slice消除编译器的边界检查
let lhs = &left[..l];
let rhs = &right[..l];
// 逐位比较,只要出现一位大于另一位就作为结果返回
let l = min(left.len(), right.len());
// 逐位比较,只要出现一位比较另一位为false就代表比较失败返回false
for i in 0..l {
match lhs[i].cmp(&rhs[i]) {
Ordering::Equal => (),
non_eq => return non_eq,
if !(left[i] == right[i]) {
return false
}
}
// 若每一位都相同就比较长度,长度也相同则代表两个buffer全等
left.len().cmp(&right.len())
return left.len() == right.len();
}
```

列表比较是不太可靠的,首先列表内只允许数字和bool,其次要保证两列表长度相同,还要保证每一位的元素基本类型相同。因此如果数字都确定不大于255可以选用buffer比较。如果数字普遍偏大则可以考虑使用u32 buffer之类的实现
Str, Instance, List, Obj也依照以上算法比较

赋值就是复制,不太好笑。。

Expand Down
7 changes: 7 additions & 0 deletions spec/self.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# self

self是一个关键词,在方法外代表顶级作用域的一个变量,不会被let self覆盖;在方法内代表方法操作的目标。

你也可以使用bind方法使一个函数的self目标改变,但由于bind行为本身会传参引起复制,使用bind(变量名)时并不会引起变量本身改变。

在方法内外都可使用self = xx语法。但在方法内使用时有可能会直接导致原变量类型改变,所以请不要把self当普通变量使用,减少预料之外的事情发生。
1 change: 1 addition & 0 deletions src/ast/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub struct ClassDefRaw {
/// 绑定作用域的类声明
#[derive(Debug, Clone)]
pub struct ClassDef {
pub name: Interned,
pub props: Vec<ClassProp>,
pub statics: Vec<ClassFunc>,
pub methods: Vec<ClassFunc>,
Expand Down
40 changes: 25 additions & 15 deletions src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub enum Litr {
Float (f64),
Bool (bool),

Func (Box<Function>), // extern和Func(){} 都属于Func直接表达式
Func (Box<Function>),
Str (Box<String>),
Buffer (Box<Vec<u8>>),
List (Box<Vec<Litr>>),
Expand Down Expand Up @@ -70,14 +70,26 @@ impl Litr {
Obj=> format!("obj"),
Inst(i)=> {
let cls = unsafe{&*i.cls};
let mut v = i.v.iter();
let mut name = cls.props.iter();
let mut val = i.v.iter();
let mut str = String::new();
str.push_str("Instance { ");
for p in cls.props.iter() {
str.push_str(&p.name.str());
str.push_str(": ");
str.push_str(&v.next().unwrap().str());
macro_rules! next {($p:ident) => {{
str.push_str(&$p.name.str());
let next_v = val.next().unwrap().str();
if next_v != "" {
str.push_str(": ");
str.push_str(&next_v);
}
}}};

str.push_str(&cls.name.str());
str.push_str(" { ");
if let Some(p) = name.next() {
next!(p);
}
for p in name {
str.push_str(", ");
next!(p);
}
str.push_str(" }");
str
Expand All @@ -94,12 +106,6 @@ pub enum Function {
Native(fn(Vec<Litr>)-> Litr),
// 脚本定义的本地函数
Local(Box<LocalFunc>),
// class X {.x()}定义的方法,提供一个ClassDef指针来判断实例是否是该类型
Method(Box<(*const ClassDef, LocalFunc)>),
// 绑定了self的method
BindedMethod(Box<(*mut Instance, LocalFunc)>),
// class X {x()}定义的静态方法,提供*mut Module来判断是否能访问私有成员
Static(Box<(*mut Module, LocalFunc)>),
// 使用extern语句得到的C函数
Extern(Box<ExternFunc>)
}
Expand All @@ -118,14 +124,18 @@ pub struct LocalFuncRaw {
pub struct LocalFunc {
/// pointer
pub ptr:*const LocalFuncRaw,
pub scope: Scope
/// 来自的作用域
pub scope: Scope,
/// 是否绑定了self
pub bound: Option<*mut Litr>,
}
impl LocalFunc {
/// 将本地函数定义和作用域绑定
pub fn new(ptr:*const LocalFuncRaw, scope: Scope)-> Self {
LocalFunc{
ptr,
scope
scope,
bound: None
}
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/intern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ impl std::fmt::Debug for Interned {
}
impl std::fmt::Display for Interned {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let s = unsafe {String::from_utf8_lossy(&**self.p)};
f.write_str(&s)
f.write_str(&self.str())
}
}
13 changes: 7 additions & 6 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,16 @@ fn main()-> ExitCode {
// }
// }));

// Top native class
// self
// prop相关的一点还没做
// self calc优化
// native cls
// 基本类型的方法
// 用cell代替ref
// 析构函数..?
// 指针self链式调用

// 传进Native的struct怎么处理?
// Obj的ord
// for i {func(){i}}内部的i是否正确
// LocalFunc in Array and obj,要不整个大一统outlive函数
// func bind
// Native outlive api
// 本地函数字面量的call行为 ||{}() ||:20;()
// ^ 或许还能开一个强制分号模式
Expand All @@ -59,7 +60,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 ast::Litr::Int(code) = exit.returned {
return ExitCode::from(code as u8);
Expand Down
Loading

0 comments on commit d46a5da

Please sign in to comment.