Skip to content

Commit

Permalink
增加模块系统
Browse files Browse the repository at this point in the history
  • Loading branch information
limuy2022 committed Feb 1, 2024
1 parent 7f3c27e commit 1297470
Show file tree
Hide file tree
Showing 7 changed files with 200 additions and 86 deletions.
Binary file modified rust/locales/zh_CN/LC_MESSAGES/trans.mo
Binary file not shown.
99 changes: 69 additions & 30 deletions rust/src/base/stdlib.rs
Original file line number Diff line number Diff line change
@@ -1,44 +1,49 @@
use std::{collections::{HashMap, HashSet}, sync::Mutex};
use crate::{
base::error::{ARGUMENT_ERROR, ARGU_NUMBER, EXPECT_TYPE},
compiler::scope::{Type, TypeAllowNull},
tvm::{stdlib::prelude::*, DynaData},
};
use lazy_static::lazy_static;
use crate::{base::error::{ARGUMENT_ERROR, ARGU_NUMBER, EXPECT_TYPE, SYNTAX_ERROR}, compiler::scope::{Type, TypeAllowNull}, tvm::DynaData};
use std::{
collections::{HashMap, HashSet},
sync::Mutex,
};

use super::{codegen::Opcode, error::{ErrorInfo, RunResult}};
use super::{
codegen::{Inst, Opcode},
error::{ErrorInfo, RunResult},
};

type StdlibFunc = fn(DynaData) -> RunResult<()>;

#[derive(Hash, PartialEq, Eq)]
#[derive(Hash, PartialEq, Eq, Clone, Debug)]
pub struct RustFunction {
pub name: String,
pub buildin_id: usize,
pub ptr : StdlibFunc,
pub ptr: StdlibFunc,
pub argvs_type: Vec<Type>,
pub return_type: TypeAllowNull
pub return_type: TypeAllowNull,
}

trait Function {
fn gen_code(&self) -> Opcode;
fn check_argvs(&self, argvs:Vec<Type>) -> Result<(), ErrorInfo> ;
pub trait FunctionInterface {
fn check_argvs(&self, argvs: Vec<Type>) -> Result<(), ErrorInfo>;
fn get_return_type(&self) -> &TypeAllowNull;
}

impl Function for RustFunction {
fn gen_code(&self) -> Opcode {
return Opcode::CallNative;
}

fn check_argvs(&self, argvs:Vec<Type>) -> Result<(), ErrorInfo> {
impl FunctionInterface for RustFunction {
fn check_argvs(&self, argvs: Vec<Type>) -> Result<(), ErrorInfo> {
if argvs.len() != self.argvs_type.len() {
return Err(ErrorInfo::new(
gettextrs::gettext!(ARGU_NUMBER, self.argvs_type.len(), argvs.len()),
gettextrs::gettext(ARGUMENT_ERROR)
))
gettextrs::gettext(ARGUMENT_ERROR),
));
}
for i in 0..self.argvs_type.len() {
if argvs[i] != self.argvs_type[i] {
if argvs[i] != self.argvs_type[i] && self.argvs_type[i] != Type::Any {
return Err(ErrorInfo::new(
gettextrs::gettext!(EXPECT_TYPE, self.argvs_type[i].origin_name, argvs[i].origin_name),
gettextrs::gettext(ARGUMENT_ERROR)
))
gettextrs::gettext!(EXPECT_TYPE, self.argvs_type[i], argvs[i]),
gettextrs::gettext(ARGUMENT_ERROR),
));
}
}
Ok(())
Expand All @@ -52,48 +57,82 @@ impl Function for RustFunction {
pub struct RustClass {
pub name: String,
pub members: HashMap<String, String>,
pub functions: HashSet<RustFunction>
pub functions: HashSet<RustFunction>,
}

lazy_static!{
lazy_static! {
static ref STD_FUNC_ID: Mutex<usize> = Mutex::new(0);
}

impl RustFunction {
pub fn new(name: String, ptr: StdlibFunc, argvs_type: Vec<Type>, return_type: TypeAllowNull) -> RustFunction {
pub fn new(
name: String,
ptr: StdlibFunc,
argvs_type: Vec<Type>,
return_type: TypeAllowNull,
) -> RustFunction {
let mut lock = STD_FUNC_ID.lock().unwrap();
let tmp = *lock;
*lock += 1;
RustFunction { name, buildin_id:tmp, ptr , return_type, argvs_type}
RustFunction {
name,
buildin_id: tmp,
ptr,
return_type,
argvs_type,
}
}
}

#[derive(Debug, Clone)]
pub struct StdlibNode {
pub name: String,
pub sons: HashMap<String, StdlibNode>,
pub functions: HashSet<RustFunction>
pub functions: HashSet<RustFunction>,
}

impl StdlibNode {
pub fn new(name: String) -> StdlibNode {
StdlibNode { name, sons: HashMap::new() , functions: HashSet::new()}
StdlibNode {
name,
sons: HashMap::new(),
functions: HashSet::new(),
}
}

pub fn add_module(&mut self, name: String) {
self.sons.insert(name.clone(), StdlibNode::new(name));
pub fn add_module(&mut self, name: String) -> StdlibNode {
let ret = StdlibNode::new(name.clone());
self.sons.insert(name, ret.clone());
ret
}

pub fn add_function(&mut self, name: RustFunction) {
self.functions.insert(name);
}

pub fn get_module<T: Iterator<Item = String>>(&self, mut path: T) -> Option<&StdlibNode> {
let item = path.next();
if item.is_none() {
return Some(self);
}
let item = item.unwrap();
return self.sons.get(&item).unwrap().get_module(path);
}
}

pub fn init() -> StdlibNode {
// init stdlib
let mut stdlib = StdlibNode::new("std".to_string());
let mut prelude = stdlib.add_module("prelude".to_string());
prelude.add_function(RustFunction::new(
"print".to_string(),
tvm_print,
vec![Type::Any],
TypeAllowNull::No,
));
stdlib
}

lazy_static! {
pub static ref STDLIB_LIST:StdlibNode = init();
pub static ref STDLIB_LIST: StdlibNode = init();
}
59 changes: 30 additions & 29 deletions rust/src/compiler/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use super::token::TokenType;
use super::TokenLex;
use super::{scope::*, InputSource};
use crate::base::codegen::{Inst, Opcode, NO_ARG};
use crate::base::stdlib::STDLIB_LIST;
use crate::base::{codegen::StaticData, error::*};
use gettextrs::gettext;
use std::cell::RefCell;
Expand Down Expand Up @@ -43,8 +44,8 @@ macro_rules! TmpExpeFunctionGen {
}
return TryErr!(istry,
Box::new(self.token_lexer.compiler_data.content.clone()),
ErrorInfo::new(gettext!(TYPE_NOT_THE_SAME, self.get_type_name(ty_now),
self.get_type_name(ty_after)), gettextrs::gettext(TYPE_ERROR)))
ErrorInfo::new(gettext!(TYPE_NOT_THE_SAME, ty_now,
ty_after), gettextrs::gettext(TYPE_ERROR)))
})*
_ => {
self.token_lexer.next_back(next_sym);
Expand All @@ -68,8 +69,8 @@ macro_rules! ExprGen {
if t1 != t2 {
return TryErr!(istry,
Box::new(self.token_lexer.compiler_data.content.clone()),
ErrorInfo::new(gettext!(TYPE_NOT_THE_SAME, self.get_type_name(t1),
self.get_type_name(t2)), gettextrs::gettext(TYPE_ERROR)))
ErrorInfo::new(gettext!(TYPE_NOT_THE_SAME, t1,
t2), gettextrs::gettext(TYPE_ERROR)))
}
Ok(t1)
}
Expand All @@ -79,20 +80,23 @@ macro_rules! ExprGen {
impl<'a> AstBuilder<'a> {
pub fn new(token_lexer: TokenLex<'a>) -> Self {
let root_scope = Rc::new(RefCell::new(SymScope::new(None)));
AstBuilder {
// 为root scope添加prelude
let mut ret = AstBuilder {
token_lexer,
staticdata: StaticData::new(),
self_scope: root_scope,
};
for i in &STDLIB_LIST.sons.get("prelude").unwrap().functions {
ret.token_lexer
.compiler_data
.const_pool
.add_id(i.name.clone());
}
}

fn get_type_name(&self, ty: TypeAllowNull) -> String {
match ty {
TypeAllowNull::Yes(ty) => {
self.token_lexer.compiler_data.const_pool.id_name[ty.name].clone()
}
TypeAllowNull::No => "null".to_string(),
}
ret.self_scope
.as_ref()
.borrow_mut()
.import_prelude(&ret.token_lexer.compiler_data.const_pool);
ret
}

ExprGen!(expr9, expr9_, factor, TokenType::Power => Opcode::Power);
Expand Down Expand Up @@ -165,7 +169,7 @@ impl<'a> AstBuilder<'a> {
.inst
.push(Inst::new(Opcode::LoadLocal, varidx));
let tt = self.self_scope.as_ref().borrow().get_type(varidx);
return Ok(TypeAllowNull::Yes(tt));
return Ok(TypeAllowNull::Yes(Type::Common(tt)));
} else {
self.token_lexer.next_back(t.clone());
return TryErr!(
Expand Down Expand Up @@ -281,14 +285,17 @@ impl<'a> AstBuilder<'a> {
.replace('.', "/"),
);
// the standard library first

if let InputSource::File(now_module_path) =
self.token_lexer.compiler_data.option.inputsource.clone()
{
let mut now_module_path = std::path::PathBuf::from(now_module_path);
now_module_path.pop();
now_module_path = now_module_path.join(path);
if now_module_path.exists() {}
let strpath = path.to_str().unwrap();
if strpath.get(0..3) == Some("std") {
} else {
if let InputSource::File(now_module_path) =
self.token_lexer.compiler_data.option.inputsource.clone()
{
let mut now_module_path = std::path::PathBuf::from(now_module_path);
now_module_path.pop();
now_module_path = now_module_path.join(path);
if now_module_path.exists() {}
}
}
Ok(())
}
Expand Down Expand Up @@ -372,12 +379,6 @@ impl<'a> AstBuilder<'a> {
if let Ok(_) = self.expr(true) {
return Ok(());
}
if let Ok(_) = self.val(false) {
let t = self.token_lexer.next_token()?;
if t.tp == TokenType::LeftSmallBrace {
// func call
}
}
return Err(RuntimeError::new(
Box::new(self.token_lexer.compiler_data.content.clone()),
ErrorInfo::new(
Expand Down
Loading

0 comments on commit 1297470

Please sign in to comment.