From 3400560e85b9a733a98d21639ee17ba6821c25ec Mon Sep 17 00:00:00 2001 From: subkey <2822448396@qq.com> Date: Wed, 14 Feb 2024 03:59:15 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=BC=E5=87=BA=E7=B1=BB=E5=9E=8B=20?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E5=85=AC=E5=BC=80=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- samples/helloworld.ks | 17 +- samples/testmod.ks | 12 +- spec/classes.md | 18 ++ src/ast.rs | 349 ---------------------- src/ast/class.rs | 56 ++++ src/ast/expr.rs | 84 ++++++ src/ast/mod.rs | 158 ++++++++++ src/ast/stmt.rs | 58 ++++ src/main.rs | 6 +- src/native.rs | 4 +- src/runtime/calc.rs | 631 +++++++++++++++++++++------------------- src/runtime/call.rs | 77 +++++ src/runtime/evil.rs | 95 ++++++ src/runtime/externer.rs | 4 +- src/runtime/mod.rs | 143 ++------- src/scan/expr.rs | 3 +- src/scan/stmt.rs | 80 +++-- 17 files changed, 963 insertions(+), 832 deletions(-) delete mode 100644 src/ast.rs create mode 100644 src/ast/class.rs create mode 100644 src/ast/expr.rs create mode 100644 src/ast/mod.rs create mode 100644 src/ast/stmt.rs create mode 100644 src/runtime/call.rs create mode 100644 src/runtime/evil.rs diff --git a/samples/helloworld.ks b/samples/helloworld.ks index 7664f35..e41e923 100644 --- a/samples/helloworld.ks +++ b/samples/helloworld.ks @@ -23,17 +23,8 @@ a // corruption }`/ -class Test { - > a:Func - > new():Test { - c: 20 - }, - > .pubmet(); - b - >c - d - .met() {} -} -let p = Test::new() +mod D:\code\rs\key-lang\samples\testmod.ks> mym +let s = mym-:MyStruct::new(); +log(s) +mym-:MyStruct::d(s); -log(p) diff --git a/samples/testmod.ks b/samples/testmod.ks index 56684ee..2f916a5 100644 --- a/samples/testmod.ks +++ b/samples/testmod.ks @@ -1,6 +1,12 @@ { let tt = "hhhh" - mod.test() { - log(tt); + mod:MyStruct { + >a + b + .d(){log("ok")} + >new():MyStruct { + b:20 + } } -} \ No newline at end of file + let s = MyStruct::new() +} diff --git a/spec/classes.md b/spec/classes.md index 32b0040..81a1458 100644 --- a/spec/classes.md +++ b/spec/classes.md @@ -47,6 +47,24 @@ class MyClass { } MyClass::new().get_a() == "a" +## 模块化 + +mod: MyClass { + ... +} + +只有\>前缀的成员才能被模块外访问。使用class而不是mod:时,>前缀无意义。 +``` +mod other.ks> mymod + +class A = mymod-:MyClass + +my_mod-:MyClass::some() + +let some = my_mod-:MyClass::some; +some(); +``` + ## obj 希望能和js的Object玩起来手感差不多 diff --git a/src/ast.rs b/src/ast.rs deleted file mode 100644 index 044b806..0000000 --- a/src/ast.rs +++ /dev/null @@ -1,349 +0,0 @@ -//! 抽象语法树 -//! -//! 是沟通scanner和runtime的桥梁,进行语法结构的定义,本身不做事 -//! -//! Native模块只支持了Rust,所以不需要repr(C) - -pub use crate::runtime::Scope; - -use std::collections::HashMap; -use crate::intern::Interned; - -/// 语句列表 -#[derive(Debug, Clone, Default)] -pub struct Statements ( - pub Vec<(usize, Stmt)> -); - - -/// 分号分隔的,statement语句 -#[derive(Debug, Clone)] -pub enum Stmt { - Empty, - - // 赋值 - Let (Box), - - // 定义类 - Class (Box), - - Mod (Box), - Export (Box), - - // Key - // Key (HashMap), // 类型声明语句 - // Impl (HashMap), // 方法定义语句 - Match, // 模式匹配 - - // 块系列 - Block (Box), // 一个普通块 - If (Box), // 条件语句 - Loop (Box), // 循环 - - // 流程控制 - Break (Box), // 中断循环并提供返回值 - Continue, // 立刻进入下一次循环 - Return (Box), // 函数返回 - - // 表达式作为语句 - Expression(Box), -} - -/// 赋值语句 -#[derive(Debug, Clone)] -pub struct AssignDef { - pub id: Interned, - pub val: Expr -} - -/// 未绑定作用域的类声明 -#[derive(Debug, Clone)] -pub struct ClassDefRaw { - pub name: Interned, - pub props: Vec, - pub pub_methods: Vec<(Interned, LocalFuncRaw)>, - pub priv_methods: Vec<(Interned, LocalFuncRaw)>, - pub pub_statics: Vec<(Interned, LocalFuncRaw)>, - pub priv_statics: Vec<(Interned, LocalFuncRaw)> -} - -/// 绑定作用域的类声明 -#[derive(Debug, Clone)] -pub struct ClassDef { - pub name: Interned, - pub props: Vec, - pub statics: Vec<(Interned, LocalFunc)>, - pub methods: Vec<(Interned, LocalFunc)> -} - -/// 类中的属性声明 -#[derive(Debug, Clone)] -pub struct ClassProp { - pub name: Interned, - pub typ: KsType, - pub public: bool -} - -/// 类实例 -#[derive(Debug, Clone)] -pub struct Instance { - pub cls: *const ClassDef, - pub v: Box<[Litr]> -} - - -#[derive(Debug, Clone)] -pub struct ModDef { - pub name: Interned, - pub funcs: Vec<(Interned, Executable)>, - pub classes: Vec<*const ClassDef> -} - -#[derive(Debug, Clone)] -pub enum ExportDef { - Func((Interned, LocalFuncRaw)) -} - - - -/// 可以出现在任何右值的,expression表达式 -#[derive(Debug, Clone)] -pub enum Expr { - Empty, - Literal(Litr), - Variant(Interned), - Kself, - - // 未绑定作用域的本地函数 - LocalDecl (Box), - - // .运算符 - Property (Box), - // -.运算符 - ModFuncAcc(Box), - // -:运算符 - ModStruAcc(Box), - // ::运算符 - ImplAccess(Box), - // 调用函数 - Call (Box), - // 创建实例 - NewInst (Box), - - // 列表表达式 - List (Box>), - Obj (Box), - - // 一元运算 ! - - Unary (Box), - // 二元运算 - Binary (Box), -} - -#[derive(Debug, Clone)] -pub struct PropDecl { - pub left: Expr, - pub right: Interned -} - -#[derive(Debug, Clone)] -pub struct BinDecl { - pub left: Expr, - pub right: Expr, - pub op: Box<[u8]> -} - -#[derive(Debug, Clone)] -pub struct UnaryDecl { - pub right: Expr, - pub op: u8 -} - -#[derive(Debug, Clone)] -pub struct AccessDecl { - pub left: Interned, - pub right: Interned -} - -#[derive(Debug, Clone)] -pub struct CallDecl { - pub args: Vec, - pub targ: Expr -} - -#[derive(Debug, Clone)] -pub struct NewDecl { - pub cls: Interned, - pub val: ObjDecl -} - - -/// 变量或字面量 -#[derive(Debug, Clone)] -pub enum Litr { - Uninit, - - Int (isize), - Uint (usize), - Float (f64), - Bool (bool), - - Func (Box), // extern和Func(){} 都属于Func直接表达式 - Str (Box), - Buffer (Box>), - List (Box>), - Obj, - Inst (Box) -} -impl Litr { - /// 由Key编译器提供的转字符 - pub fn str(&self)-> String { - use Litr::*; - match self { - Uninit => String::default(), - Int(n)=> n.to_string(), - Uint(n)=> n.to_string(), - Float(n)=> n.to_string(), - Bool(n)=> n.to_string(), - Func(f)=> { - match **f { - Executable::Local(_)=> "".to_owned(), - Executable::Extern(_)=> "".to_owned(), - _=> "".to_owned() - } - } - Str(s)=> (**s).clone(), - List(a) => { - let mut iter = a.iter(); - let mut str = String::new(); - str.push_str("["); - if let Some(v) = iter.next() { - str.push_str(&v.str()); - }; - while let Some(v) = iter.next() { - str.push_str(", "); - str.push_str(&v.str()); - } - str.push_str("]"); - str - }, - Buffer(b)=> format!("{:?}",b), - Obj=> format!("obj"), - Inst(i)=> { - let cls = unsafe{&*i.cls}; - let mut v = i.v.iter(); - let mut str = String::new(); - str.push_str(&cls.name.str()); - str.push_str(" { "); - for p in cls.props.iter() { - str.push_str(&p.name.str()); - str.push_str(": "); - str.push_str(&v.next().unwrap().str()); - str.push_str(", "); - } - str.push_str(" }"); - str - } - } - } -} - - -/// 针对函数的枚举 -#[derive(Debug, Clone)] -pub enum Executable { - Native(fn(Vec)-> Litr), // runtime提供的函数 - Local(Box), // 脚本内的定义 - Extern(Box) // 脚本使用extern获取的函数 -} - - -/// 未绑定作用域的本地定义函数 -#[derive(Debug, Clone)] -pub struct LocalFuncRaw { - pub argdecl: Vec<(Interned, KsType)>, - pub stmts: Statements -} - - -/// 本地函数指针 -#[derive(Debug, Clone)] -pub struct LocalFunc { - /// pointer - pub ptr:*const LocalFuncRaw, - pub scope: Scope -} -impl LocalFunc { - /// 将本地函数定义和作用域绑定 - pub fn new(ptr:*const LocalFuncRaw, scope: Scope)-> Self { - LocalFunc{ - ptr, - scope - } - } -} -impl std::ops::Deref for LocalFunc { - type Target = LocalFuncRaw; - fn deref(&self) -> &Self::Target { - unsafe {&*self.ptr} - } -} - -// 本地方法指针 -// #[derive(Debug, Clone)] -// pub struct LocalMethod { -// /// pointer -// pub ptr:*const LocalFuncRaw, -// pub scope: Scope, -// /// key self -// pub kself: *mut Litr -// } -// impl LocalMethod { -// /// 将本地函数定义和作用域绑定 -// pub fn new(ptr:*const LocalFuncRaw, scope: Scope, kself: *mut Litr)-> Self { -// LocalMethod { -// ptr, -// scope, -// kself -// } -// } -// } -// impl std::ops::Deref for LocalMethod { -// type Target = LocalFuncRaw; -// fn deref(&self) -> &Self::Target { -// unsafe {&*self.ptr} -// } -// } - -/// 插件只有一个Native类型 -#[derive(Debug, Clone)] -pub struct ExternFunc { - pub argdecl: Vec<(Interned, KsType)>, - pub ptr: usize, -} - - -/// Key语言内的类型声明 -/// -/// 模块不能获取程序上下文,因此KsType对Native模块无意义 -#[derive(Debug, Clone)] -pub enum KsType { - Any, - Int, - Uint, - Float, - Bool, - Func, - Str, - Buffer, - List, - Obj, - Class(Interned) -} - - -#[derive(Debug, Clone)] -pub struct ObjDecl ( - pub Vec<(Interned,Expr)> -); - diff --git a/src/ast/class.rs b/src/ast/class.rs new file mode 100644 index 0000000..d128f92 --- /dev/null +++ b/src/ast/class.rs @@ -0,0 +1,56 @@ +//! Class声明和实例 + +use crate::intern::Interned; +use crate::runtime::Module; +use crate::ast::*; + +/// 未绑定作用域的类声明 +#[derive(Debug, Clone)] +pub struct ClassDefRaw { + pub name: Interned, + pub props: Vec, + pub methods: Vec, + pub statics: Vec +} + +/// 绑定作用域的类声明 +#[derive(Debug, Clone)] +pub struct ClassDef { + pub name: Interned, + pub props: Vec, + pub statics: Vec, + pub methods: Vec, + /// 用来判断是否在模块外 + pub module: *mut Module +} + +/// 类中的属性声明 +#[derive(Debug, Clone)] +pub struct ClassProp { + pub name: Interned, + pub typ: KsType, + pub public: bool +} + +/// 类中的未绑定作用域的函数声明 +#[derive(Debug,Clone)] +pub struct ClassFuncRaw { + pub name: Interned, + pub f: LocalFuncRaw, + pub public: bool +} + +/// 类中的函数声明 +#[derive(Debug,Clone)] +pub struct ClassFunc { + pub name: Interned, + pub f: LocalFunc, + pub public: bool +} + +/// 类实例 +#[derive(Debug, Clone)] +pub struct Instance { + pub cls: *const ClassDef, + pub v: Box<[Litr]> +} diff --git a/src/ast/expr.rs b/src/ast/expr.rs new file mode 100644 index 0000000..4c2f3a1 --- /dev/null +++ b/src/ast/expr.rs @@ -0,0 +1,84 @@ +//! 表达式 +use super::*; + +/// 可以出现在任何右值的,expression表达式 +#[derive(Debug, Clone)] +pub enum Expr { + Empty, + // 字面量 + Literal(Litr), + // 变量 + Variant(Interned), + // self + Kself, + + // 未绑定作用域的本地函数 + LocalDecl (Box), + + // .运算符 + Property (Box), + // -.运算符 + ModFuncAcc(Box), + // -:运算符 + ModClsAcc (Box), + // ::运算符 + ImplAccess(Box), + // 调用函数 + Call (Box), + // 创建实例 + NewInst (Box), + + // 列表表达式 + List (Box>), + // 对象表达式 + Obj (Box), + + // 一元运算 ! - + Unary (Box), + // 二元运算 + Binary (Box), +} + +// V 注释见Expr V + +#[derive(Debug, Clone)] +pub struct PropDecl { + pub left: Expr, + pub right: Interned +} + +#[derive(Debug, Clone)] +pub struct BinDecl { + pub left: Expr, + pub right: Expr, + pub op: Box<[u8]> +} + +#[derive(Debug, Clone)] +pub struct UnaryDecl { + pub right: Expr, + pub op: u8 +} + +#[derive(Debug, Clone)] +pub struct AccessDecl { + pub left: Interned, + pub right: Interned +} + +#[derive(Debug, Clone)] +pub struct CallDecl { + pub args: Vec, + pub targ: Expr +} + +#[derive(Debug, Clone)] +pub struct NewDecl { + pub cls: Interned, + pub val: ObjDecl +} + +#[derive(Debug, Clone)] +pub struct ObjDecl ( + pub Vec<(Interned,Expr)> +); \ No newline at end of file diff --git a/src/ast/mod.rs b/src/ast/mod.rs new file mode 100644 index 0000000..c6b9c8e --- /dev/null +++ b/src/ast/mod.rs @@ -0,0 +1,158 @@ +//! 抽象语法树 +//! +//! 是沟通scanner和runtime的桥梁,进行语法结构的定义,本身不做事 +//! +//! Native模块只支持了Rust,所以不需要repr(C) + +mod class; +pub use class::*; +mod stmt; +pub use stmt::*; +mod expr; +pub use expr::*; + +use crate::runtime::Scope; +use crate::intern::Interned; + +use std::collections::HashMap; + + +/// 变量或字面量 +#[derive(Debug, Clone)] +pub enum Litr { + Uninit, + + Int (isize), + Uint (usize), + Float (f64), + Bool (bool), + + Func (Box), // extern和Func(){} 都属于Func直接表达式 + Str (Box), + Buffer (Box>), + List (Box>), + Obj, + Inst (Box) +} +impl Litr { + /// 由Key编译器提供的转字符 + pub fn str(&self)-> String { + use Litr::*; + match self { + Uninit => String::default(), + Int(n)=> n.to_string(), + Uint(n)=> n.to_string(), + Float(n)=> n.to_string(), + Bool(n)=> n.to_string(), + Func(f)=> { + match **f { + Function::Local(_)=> "".to_owned(), + Function::Extern(_)=> "".to_owned(), + _=> "".to_owned() + } + } + Str(s)=> (**s).clone(), + List(a) => { + let mut iter = a.iter(); + let mut str = String::new(); + str.push_str("["); + if let Some(v) = iter.next() { + str.push_str(&v.str()); + }; + while let Some(v) = iter.next() { + str.push_str(", "); + str.push_str(&v.str()); + } + str.push_str("]"); + str + }, + Buffer(b)=> format!("{:?}",b), + Obj=> format!("obj"), + Inst(i)=> { + let cls = unsafe{&*i.cls}; + let mut v = i.v.iter(); + let mut str = String::new(); + str.push_str(&cls.name.str()); + str.push_str(" { "); + for p in cls.props.iter() { + str.push_str(&p.name.str()); + str.push_str(": "); + str.push_str(&v.next().unwrap().str()); + str.push_str(", "); + } + str.push_str(" }"); + str + } + } + } +} + + +/// 针对函数的枚举 +#[derive(Debug, Clone)] +pub enum Function { + Native(fn(Vec)-> Litr), // runtime提供的函数 + Local(Box), // 脚本内的定义 + Method(Box<(*const ClassDef, LocalFunc)>), // class内的方法 + Extern(Box) // 脚本使用extern获取的函数 +} + + +/// 未绑定作用域的本地定义函数 +#[derive(Debug, Clone)] +pub struct LocalFuncRaw { + pub argdecl: Vec<(Interned, KsType)>, + pub stmts: Statements +} + + +/// 本地函数指针 +#[derive(Debug, Clone)] +pub struct LocalFunc { + /// pointer + pub ptr:*const LocalFuncRaw, + pub scope: Scope +} +impl LocalFunc { + /// 将本地函数定义和作用域绑定 + pub fn new(ptr:*const LocalFuncRaw, scope: Scope)-> Self { + LocalFunc{ + ptr, + scope + } + } +} +impl std::ops::Deref for LocalFunc { + type Target = LocalFuncRaw; + fn deref(&self) -> &Self::Target { + unsafe {&*self.ptr} + } +} + + +/// 插件只有一个Native类型 +#[derive(Debug, Clone)] +pub struct ExternFunc { + pub argdecl: Vec<(Interned, KsType)>, + pub ptr: usize, +} + + +/// Key语言内的类型声明 +/// +/// 模块不能获取程序上下文,因此KsType对Native模块无意义 +#[derive(Debug, Clone)] +pub enum KsType { + Any, + Int, + Uint, + Float, + Bool, + Func, + Str, + Buffer, + List, + Obj, + Class(Interned) +} + diff --git a/src/ast/stmt.rs b/src/ast/stmt.rs new file mode 100644 index 0000000..0bb3b9d --- /dev/null +++ b/src/ast/stmt.rs @@ -0,0 +1,58 @@ +//! 语句 +use super::*; + +/// 语句列表 +#[derive(Debug, Clone, Default)] +pub struct Statements ( + pub Vec<(usize, Stmt)> +); + + +/// 分号分隔的,statement语句 +#[derive(Debug, Clone)] +pub enum Stmt { + Empty, + + // 赋值 + Let (Box), + + // 定义类 + Class (Box), + + Mod (Box), + ExportFn (Box<(Interned, LocalFuncRaw)>), + ExportCls (Box), + + // Key + // Key (HashMap), // 类型声明语句 + // Impl (HashMap), // 方法定义语句 + Match, // 模式匹配 + + // 块系列 + Block (Box), // 一个普通块 + If (Box), // 条件语句 + Loop (Box), // 循环 + + // 流程控制 + Break (Box), // 中断循环并提供返回值 + Continue, // 立刻进入下一次循环 + Return (Box), // 函数返回 + + // 表达式作为语句 + Expression(Box), +} + +/// 赋值语句 +#[derive(Debug, Clone)] +pub struct AssignDef { + pub id: Interned, + pub val: Expr +} + + +#[derive(Debug, Clone)] +pub struct ModDef { + pub name: Interned, + pub funcs: Vec<(Interned, Function)>, + pub classes: Vec<*const ClassDef> +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index cab8604..35f5fc5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,8 +25,12 @@ fn main()-> ExitCode { // } // })); + // todo public指针不太对 // use和class应在scan期间解析完成 // todo self是Scope中要定义的*mut class + // .#prop提示私有 + // Class::method(self, x) + // class A = somemod-:Mod // struct obj // self calc优化 // 基本类型的方法 @@ -58,7 +62,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); diff --git a/src/native.rs b/src/native.rs index 57395eb..bf6e486 100644 --- a/src/native.rs +++ b/src/native.rs @@ -2,7 +2,7 @@ use crate::{ ast::{ - Executable, ModDef + Function, ModDef }, c::Clib, intern::{intern, Interned} @@ -24,7 +24,7 @@ pub fn parse(name:Interned,path:&[u8])-> Result { f(&mut expfns); funcs = expfns.into_iter().map(|(id, exec)|{ let ident = intern(&id); - (ident, Executable::Native(exec)) + (ident, Function::Native(exec)) }).collect(); } } diff --git a/src/runtime/calc.rs b/src/runtime/calc.rs index 8f11272..d534010 100644 --- a/src/runtime/calc.rs +++ b/src/runtime/calc.rs @@ -1,13 +1,8 @@ //! 注释都在mod.rs里,这没有注解 -use crate::{ast::{ - Executable, Expr, Litr -}, runtime::Instance}; -use super::{ - Scope, err, LocalFunc, outlive -}; - +use super::*; +/// 解析一个表达式,对应Expr pub fn calc(this:&mut Scope,e:&Expr)-> Litr { use Litr::*; match e { @@ -15,285 +10,15 @@ pub fn calc(this:&mut Scope,e:&Expr)-> Litr { Expr::Literal(litr)=> litr.clone(), - Expr::Variant(id)=> return this.var(*id).clone(), + Expr::Variant(id)=> this.var(*id).clone(), Expr::LocalDecl(local)=> { let mut f = &**local; - let exec = Executable::Local(Box::new(LocalFunc::new(f, *this))); + let exec = Function::Local(Box::new(LocalFunc::new(f, *this))); Litr::Func(Box::new(exec)) } - Expr::Binary(bin)=> { - /// 二元运算中普通数字的戏份 - macro_rules! impl_num { - ($pan:literal $op:tt) => {{ - let left = this.calc(&bin.left); - let right = this.calc(&bin.right); - impl_num!($pan,left,right $op) - }}; - ($pan:literal $op:tt $n:tt)=> {{ - let left = this.calc(&bin.left); - let right = this.calc(&bin.right); - if match right { - Int(r) => r == 0, - Uint(r) => r == 0, - Float(r) => r == 0.0, - _=> false - } {err("除数必须非0")} - impl_num!($pan,left,right $op) - }}; - ($pan:literal,$l:ident,$r:ident $op:tt) => {{ - match ($l.clone(), $r.clone()) { - (Int(l),Int(r))=> Int(l $op r), - (Uint(l),Uint(r))=> Uint(l $op r), - (Uint(l),Int(r))=> Uint(l $op r as usize), - (Float(l),Float(r))=> Float(l $op r), - (Float(l),Int(r))=> Float(l $op r as f64), - _=> err($pan) - } - }}; - } - - /// 二元运算中无符号数的戏份 - macro_rules! impl_unsigned { - ($pan:literal $op:tt) => {{ - let left = this.calc(&bin.left); - let right = this.calc(&bin.right); - match (left, right) { - (Uint(l), Uint(r))=> Uint(l $op r), - (Uint(l), Int(r))=> Uint(l $op r as usize), - _=> err($pan) - } - }}; - } - - /// 数字修改并赋值 - macro_rules! impl_num_assign { - ($o:tt) => {{ - let left = this.calc(&bin.left); - let right = this.calc(&bin.right); - if let Expr::Variant(id) = bin.left { - // 将Int自动转为对应类型 - let n = match (left, right) { - (Uint(l), Uint(r))=> Uint(l $o r), - (Uint(l), Int(r))=> Uint(l $o r as usize), - (Int(l), Int(r))=> Int(l $o r), - (Float(l), Float(r))=> Float(l $o r), - (Float(l), Int(r))=> Float(l $o r as f64), - _=> err("运算并赋值的左右类型不同") - }; - *this.var(id) = n; - return Uninit; - } - err("只能为变量赋值。"); - }}; - } - - // 无符号数修改并赋值 - macro_rules! impl_unsigned_assign { - ($op:tt) => {{ - let left = this.calc(&bin.left); - let right = this.calc(&bin.right); - if let Expr::Variant(id) = bin.left { - // 数字默认为Int,所以所有数字类型安置Int自动转换 - let n = match (left, right) { - (Uint(l), Uint(r))=> Uint(l $op r), - (Uint(l), Int(r))=> Uint(l $op r as usize), - _=> err("按位运算并赋值只允许无符号数") - }; - *this.var(id) = n; - return Uninit; - } - err("只能为变量赋值。"); - }}; - } - - /// 比大小宏 - /// - /// 需要读堆的数据类型都需要以引用进行比较,减少复制开销 - macro_rules! impl_ord {($o:tt) => {{ - fn match_basic(l:&Litr,r:&Litr)-> bool { - // 对于简单数字,复制开销并不大 - match (l.clone(), r.clone()) { - (Uint(l),Uint(r))=> l $o r, - (Uint(l),Int(r))=> l $o r as usize, - (Uint(l),Float(r))=> l $o r as usize, - (Int(l), Uint(r))=> l $o r as isize, - (Int(l), Int(r))=> l $o r, - (Int(l), Float(r))=> l $o r as isize, - (Float(l), Uint(r))=> l $o r as f64, - (Float(l), Int(r))=> l $o r as f64, - (Float(l), Float(r))=> l $o r, - (Bool(l), Bool(r))=> l $o r, - _=> err("比较两侧类型不同。") - } - } - - // mayclone会在复制时拿到复制值的所有权 - let mut l_mayclone = Litr::Uninit; - let mut l = match &bin.left { - Expr::Variant(id)=> unsafe{&*(this.var(*id) as *mut Litr)} - Expr::Literal(l)=> l, - _=> { - l_mayclone = this.calc(&bin.left); - &l_mayclone - } - }; - let mut r_mayclone = Litr::Uninit; - let mut r = match &bin.right { - Expr::Variant(id)=> unsafe{&*(this.var(*id) as *mut Litr)} - Expr::Literal(l)=> l, - _=> { - r_mayclone = this.calc(&bin.right); - &r_mayclone - } - }; - Bool(match (l, r) { - (Str(l), Str(r))=> l $o r, - (List(l), List(r))=> { - let len = l.len(); - if len != r.len() { - err("列表长度不同,无法比较"); - } - let mut b = true; - for i in 0..len { - if !match_basic(&l[i],&r[i]) { - b = false; - break; - }; - } - b - }, - (Buffer(l), Buffer(r))=> l $o r, - _=> match_basic(l,r) - }) - }}} - - /// 逻辑符 - macro_rules! impl_logic { - ($o:tt) => {{ - let mut left = this.calc(&bin.left); - let mut right = this.calc(&bin.right); - // 先把uninit同化成false - if let Uninit = left { - left = Bool(false) - } - if let Uninit = right { - right = Bool(false) - } - - match (left, right) { - (Bool(l), Bool(r))=> Bool(l $o r), - _=> err("逻辑运算符两边必须都为Bool") - } - }}; - } - - match &*bin.op { - // 数字 - b"+" => { - // 尽可能使用字符引用,避免复制字符(calc函数必定复制) - let mut left_mayclone = Litr::Uninit; - let left = match &bin.left { - Expr::Variant(id)=> unsafe{&*(this.var(*id) as *mut Litr)}, - Expr::Literal(l)=> l, - _=> { - left_mayclone = this.calc(&bin.left); - &left_mayclone - } - }; - let mut right_mayclone = Litr::Uninit; - let right = match &bin.right { - Expr::Variant(id)=> &*this.var(*id), - Expr::Literal(l)=> l, - _=> { - right_mayclone = this.calc(&bin.right); - &right_mayclone - } - }; - if let Str(l) = left { - // litr.str()方法会把内部String复制一遍 - // 直接使用原String的引用可以避免这次复制 - if let Str(r) = right { - let mut s = Box::new([l.as_str(),r.as_str()].concat()); - return Str(s); - } - let r = right.str(); - let mut s = Box::new([l.as_str(),r.as_str()].concat()); - return Str(s); - } - impl_num!("相加类型不同",left,right +) - }, - b"-" => impl_num!("相减类型不同" -), - b"*" => impl_num!("相乘类型不同" *), - b"%" => impl_num!("求余类型不同" %), - b"/" => impl_num!("相除类型不同" / 0), - - // unsigned - b"<<" => impl_unsigned!("左移需要左值无符号" <<), - b">>" => impl_unsigned!("右移需要左值无符号" >>), - b"&" => impl_unsigned!("&需要左值无符号" &), - b"^" => impl_unsigned!("^需要左值无符号" ^), - b"|" => impl_unsigned!("|需要左值无符号" |), - - // 赋值 - b"=" => { - let (left,target_scope) = match bin.left { - Expr::Variant(id)=> { - let v = this.var_with_scope(id); - (unsafe{&mut *(v.0 as *mut Litr)}, v.1) - }, - _=> return Uninit - }; - let right = this.calc(&bin.right); - // 为函数定义处增加一层引用计数 - match &right { - Litr::Func(f)=> { - if let Executable::Local(f) = &**f { - outlive::outlive_to((**f).clone(),target_scope); - } - } - Litr::List(l)=> { - l.iter().for_each(|f|if let Litr::Func(f) = f { - if let Executable::Local(f) = &**f { - outlive::outlive_to((**f).clone(),target_scope); - } - }) - } - _=> { - // todo!("Obj和Struct仍未实装"); - } - } - *left = right; - return Uninit; - } - b"+=" => impl_num_assign!(+), - b"-=" => impl_num_assign!(-), - b"*=" => impl_num_assign!(*), - b"/=" => impl_num_assign!(/), - b"%=" => impl_num_assign!(%), - - b"&=" => impl_unsigned_assign!(&), - b"^=" => impl_unsigned_assign!(^), - b"|=" => impl_unsigned_assign!(|), - b"<<=" => impl_unsigned_assign!(<<), - b">>=" => impl_unsigned_assign!(>>), - - // 比较 - b"==" => impl_ord!(==), - b"!=" => impl_ord!(!=), - b">=" => impl_ord!(>=), - b"<=" => impl_ord!(<=), - b">" => impl_ord!(>), - b"<" => impl_ord!(<), - - // 逻辑 - b"&&" => impl_logic!(&&), - b"||" => impl_logic!(||), - - _=> err(&format!("未知运算符'{}'", String::from_utf8_lossy(&bin.op))) - } - } + Expr::Binary(bin)=> binary(this, bin), Expr::Unary(una)=> { let right = this.calc(&una.right); @@ -342,33 +67,343 @@ pub fn calc(this:&mut Scope,e:&Expr)-> Litr { Expr::ModFuncAcc(acc)=> { let modname = acc.left; let funcname = acc.right; - unsafe { - for def in (*this.mods).imports.iter() { - if def.name == modname { - for (id, func) in def.funcs.iter() { - if *id == funcname { - return Litr::Func(Box::new(func.clone())); - } + let mods = unsafe {&(*this.module)}; + for def in mods.imports.iter() { + if def.name == modname { + for (id, func) in def.funcs.iter() { + if *id == funcname { + return Litr::Func(Box::new(func.clone())); } - err(&format!("模块'{}'中没有'{}'函数",modname,funcname)) } + err(&format!("模块'{}'中没有'{}'函数",modname,funcname)) } - err(&format!("当前作用域没有'{}'模块",modname)) } + err(&format!("没有导入'{}'模块",modname)) } - Expr::ImplAccess(acc)=> { - let cls = this.find_class(acc.left); - let find = acc.right; - for (id, f) in cls.statics.iter() { - if *id == find { - return Litr::Func(Box::new(Executable::Local(Box::new(f.clone())))); + Expr::Empty => err("得到空表达式"), + _=> err("算不出来 ") + } +} + +fn binary(this:&mut Scope, bin:&BinDecl)-> Litr { + use Litr::*; + /// 二元运算中普通数字的戏份 + macro_rules! impl_num { + ($pan:literal $op:tt) => {{ + let left = this.calc(&bin.left); + let right = this.calc(&bin.right); + impl_num!($pan,left,right $op) + }}; + ($pan:literal $op:tt $n:tt)=> {{ + let left = this.calc(&bin.left); + let right = this.calc(&bin.right); + if match right { + Int(r) => r == 0, + Uint(r) => r == 0, + Float(r) => r == 0.0, + _=> false + } {err("除数必须非0")} + impl_num!($pan,left,right $op) + }}; + ($pan:literal,$l:ident,$r:ident $op:tt) => {{ + match ($l.clone(), $r.clone()) { + (Int(l),Int(r))=> Int(l $op r), + (Uint(l),Uint(r))=> Uint(l $op r), + (Uint(l),Int(r))=> Uint(l $op r as usize), + (Float(l),Float(r))=> Float(l $op r), + (Float(l),Int(r))=> Float(l $op r as f64), + _=> err($pan) + } + }}; + } + + /// 二元运算中无符号数的戏份 + macro_rules! impl_unsigned { + ($pan:literal $op:tt) => {{ + let left = this.calc(&bin.left); + let right = this.calc(&bin.right); + match (left, right) { + (Uint(l), Uint(r))=> Uint(l $op r), + (Uint(l), Int(r))=> Uint(l $op r as usize), + _=> err($pan) + } + }}; + } + + /// 数字修改并赋值 + macro_rules! impl_num_assign { + ($o:tt) => {{ + let left = this.calc(&bin.left); + let right = this.calc(&bin.right); + if let Expr::Variant(id) = bin.left { + // 将Int自动转为对应类型 + let n = match (left, right) { + (Uint(l), Uint(r))=> Uint(l $o r), + (Uint(l), Int(r))=> Uint(l $o r as usize), + (Int(l), Int(r))=> Int(l $o r), + (Float(l), Float(r))=> Float(l $o r), + (Float(l), Int(r))=> Float(l $o r as f64), + _=> err("运算并赋值的左右类型不同") + }; + *this.var(id) = n; + return Uninit; + } + err("只能为变量赋值。"); + }}; + } + + // 无符号数修改并赋值 + macro_rules! impl_unsigned_assign { + ($op:tt) => {{ + let left = this.calc(&bin.left); + let right = this.calc(&bin.right); + if let Expr::Variant(id) = bin.left { + // 数字默认为Int,所以所有数字类型安置Int自动转换 + let n = match (left, right) { + (Uint(l), Uint(r))=> Uint(l $op r), + (Uint(l), Int(r))=> Uint(l $op r as usize), + _=> err("按位运算并赋值只允许无符号数") + }; + *this.var(id) = n; + return Uninit; + } + err("只能为变量赋值。"); + }}; + } + + /// 比大小宏 + /// + /// 需要读堆的数据类型都需要以引用进行比较,减少复制开销 + macro_rules! impl_ord {($o:tt) => {{ + fn match_basic(l:&Litr,r:&Litr)-> bool { + // 对于简单数字,复制开销并不大 + match (l.clone(), r.clone()) { + (Uint(l),Uint(r))=> l $o r, + (Uint(l),Int(r))=> l $o r as usize, + (Uint(l),Float(r))=> l $o r as usize, + (Int(l), Uint(r))=> l $o r as isize, + (Int(l), Int(r))=> l $o r, + (Int(l), Float(r))=> l $o r as isize, + (Float(l), Uint(r))=> l $o r as f64, + (Float(l), Int(r))=> l $o r as f64, + (Float(l), Float(r))=> l $o r, + (Bool(l), Bool(r))=> l $o r, + _=> err("比较两侧类型不同。") + } + } + + // mayclone会在复制时拿到复制值的所有权 + let mut l_mayclone = Litr::Uninit; + let mut l = match &bin.left { + Expr::Variant(id)=> unsafe{&*(this.var(*id) as *mut Litr)} + Expr::Literal(l)=> l, + _=> { + l_mayclone = this.calc(&bin.left); + &l_mayclone + } + }; + let mut r_mayclone = Litr::Uninit; + let mut r = match &bin.right { + Expr::Variant(id)=> unsafe{&*(this.var(*id) as *mut Litr)} + Expr::Literal(l)=> l, + _=> { + r_mayclone = this.calc(&bin.right); + &r_mayclone + } + }; + Bool(match (l, r) { + (Str(l), Str(r))=> l $o r, + (List(l), List(r))=> { + let len = l.len(); + if len != r.len() { + err("列表长度不同,无法比较"); + } + let mut b = true; + for i in 0..len { + if !match_basic(&l[i],&r[i]) { + b = false; + break; + }; } + b + }, + (Buffer(l), Buffer(r))=> l $o r, + _=> match_basic(l,r) + }) + }}} + + /// 逻辑符 + macro_rules! impl_logic { + ($o:tt) => {{ + let mut left = this.calc(&bin.left); + let mut right = this.calc(&bin.right); + // 先把uninit同化成false + if let Uninit = left { + left = Bool(false) + } + if let Uninit = right { + right = Bool(false) + } + + match (left, right) { + (Bool(l), Bool(r))=> Bool(l $o r), + _=> err("逻辑运算符两边必须都为Bool") } - err(&format!("'{}'中没有'{}'函数", cls.name.str(), find.str())); + }}; + } + + match &*bin.op { + // 数字 + b"+" => { + // 尽可能使用字符引用,避免复制字符(calc函数必定复制) + let mut left_mayclone = Litr::Uninit; + let left = match &bin.left { + Expr::Variant(id)=> unsafe{&*(this.var(*id) as *mut Litr)}, + Expr::Literal(l)=> l, + _=> { + left_mayclone = this.calc(&bin.left); + &left_mayclone + } + }; + let mut right_mayclone = Litr::Uninit; + let right = match &bin.right { + Expr::Variant(id)=> &*this.var(*id), + Expr::Literal(l)=> l, + _=> { + right_mayclone = this.calc(&bin.right); + &right_mayclone + } + }; + if let Str(l) = left { + // litr.str()方法会把内部String复制一遍 + // 直接使用原String的引用可以避免这次复制 + if let Str(r) = right { + let mut s = Box::new([l.as_str(),r.as_str()].concat()); + return Str(s); + } + let r = right.str(); + let mut s = Box::new([l.as_str(),r.as_str()].concat()); + return Str(s); + } + impl_num!("相加类型不同",left,right +) + }, + b"-" => impl_num!("相减类型不同" -), + b"*" => impl_num!("相乘类型不同" *), + b"%" => impl_num!("求余类型不同" %), + b"/" => impl_num!("相除类型不同" / 0), + + // unsigned + b"<<" => impl_unsigned!("左移需要左值无符号" <<), + b">>" => impl_unsigned!("右移需要左值无符号" >>), + b"&" => impl_unsigned!("&需要左值无符号" &), + b"^" => impl_unsigned!("^需要左值无符号" ^), + b"|" => impl_unsigned!("|需要左值无符号" |), + + // 赋值 + b"=" => { + let (left,target_scope) = match bin.left { + Expr::Variant(id)=> { + let v = this.var_with_scope(id); + (unsafe{&mut *(v.0 as *mut Litr)}, v.1) + }, + _=> return Uninit + }; + let right = this.calc(&bin.right); + // 为函数定义处增加一层引用计数 + match &right { + Litr::Func(f)=> { + if let Function::Local(f) = &**f { + outlive::outlive_to((**f).clone(),target_scope); + } + } + Litr::List(l)=> { + l.iter().for_each(|f|if let Litr::Func(f) = f { + if let Function::Local(f) = &**f { + outlive::outlive_to((**f).clone(),target_scope); + } + }) + } + _=> { + // todo!("Obj和Struct仍未实装"); + } + } + *left = right; + return Uninit; } + b"+=" => impl_num_assign!(+), + b"-=" => impl_num_assign!(-), + b"*=" => impl_num_assign!(*), + b"/=" => impl_num_assign!(/), + b"%=" => impl_num_assign!(%), - Expr::Empty => err("得到空表达式"), - _=> err("算不出来 ") + b"&=" => impl_unsigned_assign!(&), + b"^=" => impl_unsigned_assign!(^), + b"|=" => impl_unsigned_assign!(|), + b"<<=" => impl_unsigned_assign!(<<), + b">>=" => impl_unsigned_assign!(>>), + + // 比较 + b"==" => impl_ord!(==), + b"!=" => impl_ord!(!=), + b">=" => impl_ord!(>=), + b"<=" => impl_ord!(<=), + b">" => impl_ord!(>), + b"<" => impl_ord!(<), + + // 逻辑 + b"&&" => impl_logic!(&&), + b"||" => impl_logic!(||), + + // 访问类成员 + b"::" => { + /// 在class中找一个函数 + fn find_fn(cls:&ClassDef, find:Interned, this_module:*mut Module)->Litr { + for func in cls.statics.iter() { + if func.name == find { + if !func.public && cls.module != this_module { + err(&format!("静态方法'{}'是私有的。",find)) + } + return Litr::Func(Box::new(Function::Local(Box::new(func.f.clone())))); + } + } + for func in cls.methods.iter() { + if !func.public && cls.module != this_module { + err(&format!("方法'{}'是私有的。",find)) + } + if func.name == find { + return Litr::Func(Box::new(Function::Method(Box::new((cls, func.f.clone()))))); + } + } + err(&format!("'{}'中没有'{}'函数", cls.name.str(), find.str())); + } + if let Expr::Variant(find) = bin.right { + if let Expr::Variant(id) = bin.left { + let cls = this.find_class(id); + return find_fn(cls, find, this.module); + } + + if let Expr::ModClsAcc(acc) = &bin.left { + let modname = acc.left; + let clsname = acc.right; + let mods = unsafe {&(*this.module)}; + for def in mods.imports.iter() { + if def.name == modname { + for cls in def.classes.iter() { + let deref = unsafe{&**cls}; + if deref.name == clsname { + return find_fn(deref, find, this.module) + } + } + err(&format!("模块'{}'中没有'{}'类型",modname,clsname)) + } + } + err(&format!("没有导入'{}'模块",modname)) + } + } + err("::右必须是标识符") + } + + _=> err(&format!("未知运算符'{}'", String::from_utf8_lossy(&bin.op))) } } \ No newline at end of file diff --git a/src/runtime/call.rs b/src/runtime/call.rs new file mode 100644 index 0000000..0322c8d --- /dev/null +++ b/src/runtime/call.rs @@ -0,0 +1,77 @@ +use super::*; + +/// 解析Expr的调用 +pub fn call(this:&mut Scope, call: &Box)-> Litr { + // 将参数解析为参数列表 + let args = call.args.iter().map(|e|this.calc(e)).collect(); + let targ = this.calc(&call.targ); + if let Litr::Func(exec) = targ { + use Function::*; + return match *exec { + Native(f)=> f(args), + Local(f)=> this.call_local(&f, args), + Method(f)=> { + let mut de = std::collections::VecDeque::from(args); + if let Some(kself) = de.pop_front() { + if let Litr::Inst(mut inst) = kself { + if inst.cls != f.0 {err("self与该class类型不同")} + this.call_method(&f.1, &mut *inst, Vec::from(de)) + }else { + err("self不是一个类的实例") + } + }else{err("方法需要提供第一个参数作为self")} + } + Extern(f)=> this.call_extern(&f, args), + } + } + err(&format!("'{:?}' 不是一个函数", targ)) +} + +/// 实际调用一个local function +pub fn call_local(this:&Scope, f:&LocalFunc, args:Vec)-> Litr { + // 将传入参数按定义参数数量放入作用域 + let mut vars = Vec::with_capacity(16); + let mut args = args.into_iter(); + for (name,ty) in f.argdecl.iter() { + let arg = args.next().unwrap_or(Litr::Uninit); + vars.push((*name,arg)) + } + + 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, + class_defs:Vec::new(), + kself: this.kself, + vars, + module: this.module, + outlives: Outlives::new() + }); + scope.run(&f.stmts); + ret +} + +/// 调用本地函数,但会绑定自定义self +pub fn call_method(this:&Scope, f:&LocalFunc, kself:*mut Instance, args:Vec)-> Litr { + let mut vars = Vec::with_capacity(16); + let mut args = args.into_iter(); + for (name,ty) in f.argdecl.iter() { + let arg = args.next().unwrap_or(Litr::Uninit); + vars.push((*name,arg)) + } + + 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, + class_defs:Vec::new(), + kself, + vars, + module: this.module, + outlives: Outlives::new() + }); + scope.run(&f.stmts); + ret +} \ No newline at end of file diff --git a/src/runtime/evil.rs b/src/runtime/evil.rs new file mode 100644 index 0000000..2482491 --- /dev/null +++ b/src/runtime/evil.rs @@ -0,0 +1,95 @@ +use super::*; + +/// 解析一个语句,对应Stmt +pub fn evil(this:&mut Scope, code:&Stmt) { + use Stmt::*; + match code { + // 只有表达式的语句 + Expression(e)=> { + // 如果你只是在一行里空放了一个变量就不会做任何事 + if let Expr::Variant(_)=&**e { + return; + } + this.calc(e); + } + // let语句 + Let(a)=> { + let mut v = this.calc(&a.val); + // 不检查变量是否存在是因为寻找变量的行为是反向的 + this.vars.push((a.id, v)); + } + // 块语句 + Block(s)=> { + let mut scope = Scope::new(ScopeInner { + parent:Some(*this), + return_to: this.return_to, + class_defs:Vec::new(), + kself: this.kself, + vars: Vec::with_capacity(16), + module: this.module, + outlives: Outlives::new() + }); + scope.run(s); + } + + // 类型声明 + Class(raw)=> { + // 为函数声明绑定作用域 + let binder = |v:&ClassFuncRaw| { + ClassFunc { name: v.name, f: LocalFunc::new(&v.f, *this), public: v.public} + }; + let methods:Vec<_> = raw.methods.iter().map(binder).collect(); + let statics:Vec<_> = raw.statics.iter().map(binder).collect(); + let props = raw.props.clone(); + let module = this.module; + let clsdef = ClassDef {name:raw.name, props, statics, methods, module}; + this.class_defs.push(clsdef); + } + + // 导入模块 + Mod(m)=> { + unsafe { + (*this.module).imports.push((**m).clone()); + } + } + // 导出函数 mod. + ExportFn(e)=> { + // 将函数本体生命周期拉为static + let func_raw = Box::leak(Box::new(e.1.clone())); + let id = e.0; + let f = LocalFunc::new(func_raw, *this); + // 将函数定义处的作用域生命周期永久延长 + outlive::outlive_static(f.scope); + let exec = Function::Local(Box::new(f)); + this.vars.push((id, Litr::Func(Box::new(exec.clone())))); + unsafe{(*this.module).export.funcs.push((id,exec))} + } + + // 导出类 mod: + ExportCls(raw)=> { + // 为函数声明绑定作用域 + let binder = |v:&ClassFuncRaw| { + // 延长函数体生命周期 + let ptr = Box::leak(Box::new(v.f.clone())); + ClassFunc { name: v.name, f: LocalFunc::new(ptr, *this), public: v.public} + }; + // 延长作用域生命周期 + outlive::outlive_static(*this); + + let methods:Vec<_> = raw.methods.iter().map(binder).collect(); + let statics:Vec<_> = raw.statics.iter().map(binder).collect(); + let props = raw.props.clone(); + let module = this.module; + let clsdef = ClassDef {name:raw.name, props, statics, methods, module}; + this.class_defs.push(clsdef); + + // 将指针推到export + let ptr = this.class_defs.last().unwrap(); + let module = this.module; + unsafe{(*module).export.classes.push(ptr)} + } + + Return(_)=> err("return语句不应被直接evil"), + _=> {} + } +} \ No newline at end of file diff --git a/src/runtime/externer.rs b/src/runtime/externer.rs index 36531f0..23aa2c9 100644 --- a/src/runtime/externer.rs +++ b/src/runtime/externer.rs @@ -58,7 +58,7 @@ pub fn translate(arg:Litr)-> Result { Buffer(v)=> Ok(v.as_ptr() as usize), Func(p)=> { let exec = unsafe {&*p}; - use crate::ast::Executable::*; + use crate::ast::Function::*; match exec { Local(f)=> translate_local_impl! { f 0 agent0 () @@ -76,7 +76,7 @@ pub fn translate(arg:Litr)-> Result { } List(_)=> Err("列表类型不可作为C指针传递".to_string()), Obj=> Err("Ks对象不可作为C指针传递".to_string()), - Inst(_)=> Err("Ks实例不可作为C指针传递".to_string()) + Inst(_)=> Err("Ks实例不可作为C指针传递".to_string()), } } diff --git a/src/runtime/mod.rs b/src/runtime/mod.rs index 649f4e0..8e291e4 100644 --- a/src/runtime/mod.rs +++ b/src/runtime/mod.rs @@ -11,7 +11,9 @@ use std::ptr::NonNull; mod outlive; pub use outlive::Outlives; mod io; +mod evil; mod calc; +mod call; mod externer; @@ -23,6 +25,8 @@ pub fn err(s:&str)-> ! { panic!("{} 运行时({})", s, unsafe{LINE}) } +// 是runtime单方面使用的,不需要定义到ast +/// 当前Ks的模块 #[derive(Debug)] pub struct Module { pub imports: Vec, @@ -31,25 +35,22 @@ pub struct Module { /// 一个运行时作用域 -/// -/// run函数需要mut因为需要跟踪行数 -/// -/// return_to是用来标志一个函数是否返回过了。 -/// 如果没返回,Some()里就是返回值要写入的指针 #[derive(Debug)] pub struct ScopeInner { /// 父作用域 - parent: Option, + pub parent: Option, /// 返回值指针,None代表已返回 - return_to: *mut Option<*mut Litr>, + pub return_to: *mut Option<*mut Litr>, /// (变量名,值) - vars: Vec<(Interned, Litr)>, + pub vars: Vec<(Interned, Litr)>, /// 类型声明 - class_defs: Vec, + pub class_defs: Vec, + /// self指针 + pub kself: *mut Instance, /// 导入和导出的模块指针 - mods: *mut Module, + pub module: *mut Module, /// 该作用域生命周期会被outlive的函数延长 - outlives: outlive::Outlives + pub outlives: outlive::Outlives } @@ -129,117 +130,22 @@ impl Scope { /// 在作用域解析一个语句 pub fn evil(&mut self, code:&Stmt) { - use Stmt::*; - match code { - // 只有表达式的语句 - Expression(e)=> { - // 如果你只是在一行里空放了一个变量就不会做任何事 - if let Expr::Variant(_)=&**e { - return; - } - self.calc(e); - } - // let语句 - Let(a)=> { - let mut v = self.calc(&a.val); - // 不检查变量是否存在是因为寻找变量的行为是反向的 - self.vars.push((a.id, v)); - } - // 块语句 - Block(s)=> { - let mut scope = Scope::new(ScopeInner { - parent:Some(*self), - return_to: self.return_to, - class_defs:Vec::new(), - vars: Vec::with_capacity(16), - mods: self.mods, - outlives: Outlives::new() - }); - scope.run(s); - } - // 导入模块 - Mod(m)=> { - unsafe { - (*self.mods).imports.push((**m).clone()); - } - } - // 导出给自己的模块 - Export(e)=> { - match &**e { - ExportDef::Func((id, f)) => { - let f = LocalFunc::new(f,*self); - // 将函数定义处的作用域生命周期永久延长 - outlive::outlive_static(f.scope); - let exec = Executable::Local(Box::new(f)); - self.vars.push((*id, Litr::Func(Box::new(exec.clone())))); - unsafe{(*self.mods).export.funcs.push((*id,exec))} - } - } - } - // 类型声明 - Class(cls)=> { - let methods:Vec<(Interned, LocalFunc)> = cls.pub_methods.iter() - .chain(cls.priv_methods.iter()) - .map(|v|(v.0, LocalFunc::new(&v.1, *self))).collect(); - let statics:Vec<(Interned, LocalFunc)> = cls.pub_statics.iter() - .chain(cls.priv_statics.iter()) - .map(|v|(v.0, LocalFunc::new(&v.1, *self))).collect(); - let props = cls.props.clone(); - self.class_defs.push(ClassDef {name:cls.name,props,statics,methods}); - } - Return(_)=> err("return语句不应被直接evil"), - _=> {} - } + evil::evil(self, code) } /// 调用一个函数 pub fn call(&mut self, call: &Box)-> Litr { - // 将参数解析为参数列表 - let args = call.args.iter().map(|e|self.calc(e)).collect(); - - // 如果是直接对变量调用则不需要使用calc函数 - let mut targ_mayclone = Litr::Uninit; - let targ = match &call.targ { - Expr::Variant(id)=> unsafe{&*(self.var(*id) as *mut Litr)} - Expr::Literal(l)=> l, - _=> { - targ_mayclone = self.calc(&call.targ); - &targ_mayclone - } - }; - if let Litr::Func(exec) = targ { - use Executable::*; - return match &**exec { - Native(f)=> f(args), - Local(f)=> self.call_local(&f, args), - Extern(f)=> self.call_extern(&f, args) - } - } - err(&format!("'{:?}' 不是一个函数", targ)) + call::call(self, call) } /// 调用本地定义的函数 pub fn call_local(&self, f:&LocalFunc, args:Vec)-> Litr { - // 将传入参数按定义参数数量放入作用域 - let mut vars = Vec::with_capacity(16); - let mut args = args.into_iter(); - for (name,ty) in f.argdecl.iter() { - let arg = args.next().unwrap_or(Litr::Uninit); - vars.push((*name,arg)) - } + call::call_local(self, f, args) + } - 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, - class_defs:Vec::new(), - vars, - mods: self.mods, - outlives: Outlives::new() - }); - scope.run(&f.stmts); - ret + /// 调用method + pub fn call_method(&self, f:&LocalFunc, kself:*mut Instance, args:Vec)-> Litr { + call::call_method(self, f, kself, args) } /// 调用extern函数 @@ -325,17 +231,20 @@ pub fn run(s:&Statements)-> RunResult { /// 创建顶级作用域 /// /// 自定义此函数可添加初始函数和变量 -pub fn top_scope(return_to:*mut Option<*mut Litr>, mods:*mut Module)-> Scope { +pub fn top_scope(return_to:*mut Option<*mut Litr>, module:*mut Module)-> Scope { let mut vars = Vec::<(Interned, Litr)>::with_capacity(16); vars.push((intern(b"log"), - Litr::Func(Box::new(Executable::Native(io::log)))) + Litr::Func(Box::new(Function::Native(io::log)))) ); + + let cls = ClassDef{methods:Vec::new(),name:intern(b""),props:Vec::new(),statics:Vec::new(),module}; + let mut kself = Instance {cls:&cls, v:[].into()}; Scope::new(ScopeInner { parent: None, return_to, class_defs:Vec::new(), - vars, mods, + kself: &mut kself, + vars, module, outlives: Outlives::new() }) } - diff --git a/src/scan/expr.rs b/src/scan/expr.rs index 653232a..8abb3d5 100644 --- a/src/scan/expr.rs +++ b/src/scan/expr.rs @@ -53,8 +53,7 @@ pub fn with_left(this:&Scanner, left:Expr)-> Expr { } }}} impl_access!(b"-.",ModFuncAcc); - impl_access!(b"-:",ModStruAcc); - impl_access!(b"::",ImplAccess); + impl_access!(b"-:",ModClsAcc); expr_stack.push(Expr::Binary(Box::new(BinDecl { left: second_last_expr, diff --git a/src/scan/stmt.rs b/src/scan/stmt.rs index f41c342..502a4b4 100644 --- a/src/scan/stmt.rs +++ b/src/scan/stmt.rs @@ -49,17 +49,17 @@ pub fn stmt(this:&Scanner)-> Stmt { let ident = this.ident(); if let Some(id) = ident { - return match id { + match id { // 如果是关键词,就会让对应函数处理关键词之后的信息 - b"let"=> letting(this), + b"let"=> Stmt::Let(letting(this)), b"extern"=> {externing(this);Stmt::Empty}, b"return"=> returning(this), - b"class"=> classing(this), + b"class"=> Stmt::Class(classing(this)), b"mod"=> moding(this), _=> { let id = Expr::Variant(intern(id)); let expr = Box::new(this.expr_with_left(id)); - return Stmt::Expression(expr); + Stmt::Expression(expr) } } }else { @@ -67,13 +67,13 @@ pub fn stmt(this:&Scanner)-> Stmt { if let Expr::Empty = expr { this.err(&format!("请输入一行正确的语句,'{}'并不合法", String::from_utf8_lossy(&[this.cur()]))) } - return Stmt::Expression(Box::new(expr)); + Stmt::Expression(Box::new(expr)) } } /// 解析let关键词 -fn letting(this:&Scanner)-> Stmt { +fn letting(this:&Scanner)-> Box { this.spaces(); let id = this.ident().unwrap_or_else(||this.err("let后需要标识符")); let id = intern(id); @@ -88,9 +88,9 @@ fn letting(this:&Scanner)-> Stmt { if let Expr::Empty = val { this.err("无法为空气赋值") } - return Stmt::Let(Box::new(AssignDef { + return Box::new(AssignDef { id, val - })); + }); } b'(' => { this.next(); @@ -111,15 +111,15 @@ fn letting(this:&Scanner)-> Stmt { // 其生命周期应当和Statements相同,绑定作用域时将被复制 // 绑定作用域行为发生在runtime::Scope::calc let func = Box::new(LocalFuncRaw { argdecl: args, stmts }); - return Stmt::Let(Box::new(AssignDef { + return Box::new(AssignDef { id, val: Expr::LocalDecl(func) - })); + }); } _ => { - return Stmt::Let(Box::new(AssignDef { + return Box::new(AssignDef { id, val:Expr::Literal(Litr::Uninit) - })); + }); } } } @@ -185,7 +185,7 @@ fn externing(this:&Scanner) { String::from_utf8_lossy(sym)))); this.push(Stmt::Let(Box::new(AssignDef { id:intern($id), - val: Expr::Literal(Litr::Func(Box::new(Executable::Extern(Box::new(ExternFunc { + val: Expr::Literal(Litr::Func(Box::new(Function::Extern(Box::new(ExternFunc { argdecl, ptr }))))) @@ -226,7 +226,7 @@ fn returning(this:&Scanner)-> Stmt { /// 解析类声明 -fn classing(this:&Scanner)-> Stmt { +fn classing(this:&Scanner)-> Box { this.spaces(); let id = this.ident().unwrap_or_else(||this.err("class后需要标识符")); this.spaces(); @@ -236,13 +236,11 @@ fn classing(this:&Scanner)-> Stmt { this.next(); let mut props = Vec::new(); - let mut pub_methods = Vec::new(); - let mut priv_methods = Vec::new(); - let mut pub_statics = Vec::new(); - let mut priv_statics = Vec::new(); + let mut methods = Vec::new(); + let mut statics = Vec::new(); loop { this.spaces(); - let publiced = if this.cur() == b'>' { + let public = if this.cur() == b'>' { this.next();this.spaces();true }else {false}; @@ -273,25 +271,17 @@ fn classing(this:&Scanner)-> Stmt { Statements(vec![(this.line(), stmt)]) }; - let v = (intern(id), LocalFuncRaw{argdecl:args,stmts}); - if publiced { - if is_method { - pub_methods.push(v) - }else { - pub_statics.push(v) - } + let v = ClassFuncRaw {name: intern(id), f:LocalFuncRaw{argdecl:args,stmts}, public}; + if is_method { + methods.push(v); }else { - if is_method { - priv_methods.push(v) - }else { - priv_statics.push(v) - } + statics.push(v); } // 属性 }else { let typ = this.typ(); let v = ClassProp { - name: intern(id), typ, public:publiced + name: intern(id), typ, public }; props.push(v); } @@ -308,9 +298,9 @@ fn classing(this:&Scanner)-> Stmt { this.err("class大括号未闭合"); } this.next(); - Stmt::Class(Box::new(ClassDefRaw { - name:intern(id), props, pub_methods, pub_statics, priv_methods, priv_statics - })) + Box::new(ClassDefRaw { + name:intern(id), props, methods, statics + }) } @@ -321,17 +311,17 @@ fn moding(this:&Scanner)-> Stmt { b'.' => { this.next(); // 套用let声明模板 - let stmt = letting(this); - if let Stmt::Let(assign) = stmt { - let AssignDef { id, val } = *assign; - if let Expr::LocalDecl(f) = val { - return Stmt::Export(Box::new(ExportDef::Func((id, (*f).clone())))); - } - this.err("模块只能导出本地函数。\n 若导出外界函数请用本地函数包裹。") + let asn = letting(this); + if let Expr::LocalDecl(f) = asn.val { + return Stmt::ExportFn(Box::new((asn.id, (*f).clone()))); } - unreachable!(); + this.err("模块只能导出本地函数。\n 若导出外界函数请用本地函数包裹。") }, - b':' => todo!(), + b':' => { + this.next(); + let cls = classing(this); + return Stmt::ExportCls(cls); + } _=>{} }; // 截取路径 @@ -341,7 +331,7 @@ fn moding(this:&Scanner)-> Stmt { let mut dot = 0; loop { if i >= len { - this.err("extern后需要 > 符号"); + this.err("mod后需要 > 符号"); } let cur = this.src[i]; if cur == b'>' {