Skip to content

Commit

Permalink
finish function return
Browse files Browse the repository at this point in the history
  • Loading branch information
limuy2022 committed Mar 24, 2024
1 parent 7fb3b9d commit 6a57882
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 46 deletions.
13 changes: 6 additions & 7 deletions examples/fast_pow.trc
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ func fastpow(a: int, b: int) int {
if b == 0 {
return 1
}
if b == 1 {
return a
}
tmp := fastpow(a, b / 2);
tmp = tmp * tmp;
tmp := fastpow(a, b // 2)
tmp = tmp * tmp
if b % 2 != 0 {
tmp = tmp * a
tmp = tmp * a
}
return tmp;
return tmp
}

print("{}", fastpow(2, 3))
13 changes: 13 additions & 0 deletions examples/func_call.trc
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
func t1(a: int, b: int, c: int) {
println("{}{}{}", a, b, c)
}

func test_complex(a:int) {
if a==89 {
print("i am 89")
}
if a ==90{
print("i am 90")
}
}

func oo(p: int) {
oo(p/2)
}
t1(90, 89, 77)
a:=9
b:=8
Expand Down
3 changes: 3 additions & 0 deletions examples/if.trc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ a:=90
if a==90 {
println("i equal to 90")
}
if a==89 {
println("i equal to 89")
}
if a < 89 {
println("i less than 90")
} else {
Expand Down
1 change: 1 addition & 0 deletions locales/en.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ unexpected_token = "token %{0} is not expected"
unclosed_comment = "unclosed comment"
char_error = "char should be the format like 'x'."
expected_expr = "expected expression"
return_should_in_function = "return should in function"

[compiler.symbolerror]
not_found_sym = "Symbol %{0} not found"
Expand Down
1 change: 1 addition & 0 deletions locales/zh-CN.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ unclosed_comment = "未闭合的注释"
prefix_float = "前缀%{0}不能对浮点数使用"
unexpected_token = "token %{0}不是被期望的"
expected_expr = "期望表达式"
return_should_in_function = "return必须在函数内部"

[compiler.symbolerror]
not_found_sym = "未找到符号%{0}"
Expand Down
1 change: 1 addition & 0 deletions src/base/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub const UNCLODED_COMMENT: &str = "compiler.syntaxerror.unclosed_comment";
pub const UNCLOSED_FORMAT: &str = "compiler.formatstringerror.unclosed_format";
pub const ARGUMENT_CANNOT_BE_VOID: &str = "compiler.argumenterror.void_argu";
pub const JUST_ACCEPT_BOOL: &str = "compiler.typerror.if_while_accept_bool";
pub const RETURN_SHOULD_IN_FUNCTION: &str = "compiler.syntaxerror.return_should_in_function";

#[derive(Debug)]
pub struct ErrorInfo {
Expand Down
92 changes: 65 additions & 27 deletions src/compiler/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@ impl<'a> AstBuilder<'a> {
let name_id = match self.self_scope.as_ref().borrow_mut().insert_sym(funcname) {
Some(v) => v,
None => {
return self.report_error(ErrorInfo::new(
return self.gen_error(ErrorInfo::new(
t!(
SYMBOL_REDEFINED,
"0" = self.token_lexer.const_pool.id_name[funcname]
Expand All @@ -544,22 +544,25 @@ impl<'a> AstBuilder<'a> {
self.get_token_checked(TokenType::Colon)?;
ty_list.push(self.get_ty(false)?);
}
let tmp = self.token_lexer.next_token()?;
let return_ty = match tmp.tp {
TokenType::Arrow => TypeAllowNull::Yes(self.get_ty(false)?),
_ => {
self.token_lexer.next_back(tmp);
TypeAllowNull::No
}
// 返回值解析
let return_ty = match self.get_ty(true) {
Err(_) => TypeAllowNull::No,
Ok(ty) => TypeAllowNull::Yes(ty),
};
let io = IOType::new(ty_list, return_ty, false);
self.get_token_checked(TokenType::LeftBigBrace)?;
let mut function_body = vec![];
let mut cnt = 1;
loop {
let t = self.token_lexer.next_token()?;
function_body.push((t.clone(), self.token_lexer.compiler_data.context.get_line()));
if t.tp == RightBigBrace {
break;
cnt -= 1;
if cnt == 0 {
break;
}
} else if t.tp == TokenType::LeftBigBrace {
cnt += 1;
}
}
// self.self_scope = tmp.clone();
Expand Down Expand Up @@ -637,7 +640,7 @@ impl<'a> AstBuilder<'a> {
let sym_idx = match self.self_scope.as_ref().borrow_mut().insert_sym(name) {
Some(v) => v,
None => {
return self.report_error(ErrorInfo::new(
return self.gen_error(ErrorInfo::new(
t!(
SYMBOL_REDEFINED,
"0" = self.token_lexer.const_pool.id_name[name]
Expand All @@ -662,7 +665,7 @@ impl<'a> AstBuilder<'a> {
let var_type = match self.process_info.get_last_ty() {
Some(v) => v,
None => {
return self.report_error(ErrorInfo::new(t!(EXPECTED_EXPR), t!(SYNTAX_ERROR)));
return self.gen_error(ErrorInfo::new(t!(EXPECTED_EXPR), t!(SYNTAX_ERROR)));
}
};
self.new_var(name, var_type)?;
Expand All @@ -674,13 +677,13 @@ impl<'a> AstBuilder<'a> {
let var_type = match self.process_info.get_last_ty() {
Some(v) => v,
None => {
return self.report_error(ErrorInfo::new(t!(EXPECTED_EXPR), t!(SYNTAX_ERROR)));
return self.gen_error(ErrorInfo::new(t!(EXPECTED_EXPR), t!(SYNTAX_ERROR)));
}
};
let var = match self.self_scope.as_ref().borrow().get_var(name) {
Some(v) => v,
None => {
return self.report_error(ErrorInfo::new(
return self.gen_error(ErrorInfo::new(
t!(
SYMBOL_NOT_FOUND,
"0" = self.token_lexer.const_pool.id_name[name]
Expand All @@ -690,7 +693,7 @@ impl<'a> AstBuilder<'a> {
}
};
if var.ty != var_type {
return self.report_error(ErrorInfo::new(t!(TYPE_NOT_THE_SAME), t!(TYPE_ERROR)));
return self.gen_error(ErrorInfo::new(t!(TYPE_NOT_THE_SAME), t!(TYPE_ERROR)));
}
self.modify_var(var.ty, var.addr, self.process_info.is_global);
Ok(())
Expand All @@ -712,11 +715,11 @@ impl<'a> AstBuilder<'a> {
self.expr(false)?;
match self.process_info.stack_type.last() {
None => {
return self.report_error(ErrorInfo::new(t!(EXPECTED_EXPR), t!(SYNTAX_ERROR)));
return self.gen_error(ErrorInfo::new(t!(EXPECTED_EXPR), t!(SYNTAX_ERROR)));
}
Some(ty) => {
if *ty != self.cache.boolty_id {
return self.report_error(ErrorInfo::new(t!(JUST_ACCEPT_BOOL), t!(TYPE_ERROR)));
return self.gen_error(ErrorInfo::new(t!(JUST_ACCEPT_BOOL), t!(TYPE_ERROR)));
}
}
}
Expand Down Expand Up @@ -763,6 +766,19 @@ impl<'a> AstBuilder<'a> {
fn statement(&mut self) -> RunResult<()> {
let t = self.token_lexer.next_token()?;
match t.tp {
TokenType::Return => {
if self.process_info.is_global {
return self.gen_error(ErrorInfo::new(
t!(RETURN_SHOULD_IN_FUNCTION),
t!(SYNTAX_ERROR),
));
}
// ignore the result
// for return and return expr both
self.expr(true).ok();
self.add_bycode(Opcode::PopFrame, NO_ARG);
return Ok(());
}
TokenType::Func => {
self.def_func()?;
return Ok(());
Expand Down Expand Up @@ -845,23 +861,17 @@ impl<'a> AstBuilder<'a> {
for i in body.iter().rev() {
self.token_lexer.next_back(i.0.clone());
}
let mut is_pop = false;
loop {
let t = self.token_lexer.next_token()?;
if t.tp == RightBigBrace {
break;
}
is_pop = false;
if t.tp == TokenType::Return {
self.expr(false)?;
self.add_bycode(Opcode::PopFrame, NO_ARG);
is_pop = true;
} else {
self.token_lexer.next_back(t);
self.statement()?;
}
self.token_lexer.next_back(t);
self.statement()?;
}
if !is_pop {
if !self.staticdata.inst.is_empty()
&& self.staticdata.inst.last().unwrap().opcode != Opcode::PopFrame
{
self.add_bycode(Opcode::PopFrame, NO_ARG);
}
self.generate_func_in_scope()?;
Expand Down Expand Up @@ -1060,6 +1070,34 @@ mod tests {
);
}

#[test]
fn test_expr_in_arg() {
gen_test_env!(
r#"
a:=90
print("{}", a+90)"#,
t
);
t.generate_code().unwrap();
assert_eq!(
t.staticdata.inst,
vec![
Inst::new(Opcode::LoadInt, 2),
Inst::new(Opcode::StoreGlobalInt, get_offset(0)),
Inst::new(Opcode::LoadString, 0),
Inst::new(Opcode::LoadGlobalVarInt, get_offset(0)),
Inst::new(Opcode::LoadInt, 2),
Inst::new(Opcode::AddInt, NO_ARG),
Inst::new(Opcode::MoveInt, NO_ARG),
Inst::new(Opcode::LoadInt, INT_VAL_POOL_ONE),
Inst::new(
Opcode::CallNative,
get_prelude_function("print").unwrap().buildin_id
),
]
)
}

#[test]
fn test_call_builtin_function() {
gen_test_env!(r#"print("hello world!")"#, t);
Expand Down
9 changes: 3 additions & 6 deletions src/compiler/ast/ast_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,12 @@ impl<'a> AstBuilder<'a> {
self.first_func = false
}

pub fn report_error<T>(&self, info: ErrorInfo) -> AstError<T> {
self.token_lexer.compiler_data.report_compiler_error(info)
}

#[inline]
pub fn try_err<T>(&self, istry: bool, info: ErrorInfo) -> AstError<T> {
if istry {
Err(LightFakeError::new().into())
} else {
self.report_error(info)
self.gen_error(info)
}
}

Expand Down Expand Up @@ -116,12 +112,13 @@ impl<'a> AstBuilder<'a> {
}

pub fn gen_error<T>(&self, e: ErrorInfo) -> AstError<T> {
self.try_err(false, e)
self.token_lexer.compiler_data.report_compiler_error(e)
}

pub fn get_token_checked(&mut self, ty: TokenType) -> AstError<Token> {
let t = self.token_lexer.next_token()?;
if t.tp != ty {
self.token_lexer.next_back(t.clone());
self.gen_error(ErrorInfo::new(
t!(UNEXPECTED_TOKEN, "0" = t.tp),
t!(SYNTAX_ERROR),
Expand Down
12 changes: 6 additions & 6 deletions src/tools/dis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ pub fn dis(opt: crate::compiler::Option) -> RunResult<()> {
let mut compiler = crate::compiler::Compiler::new(opt);
let mut ast = compiler.lex()?;
let static_data = ast.prepare_get_static();
for i in &static_data.inst {
print!("{}", i);
match i.opcode {
LoadInt => print!("({})", static_data.constpool.intpool[i.operand]),
LoadString => print!("({})", static_data.constpool.stringpool[i.operand]),
LoadFloat => print!("({})", static_data.constpool.floatpool[i.operand]),
for i in static_data.inst.iter().enumerate() {
print!("{} {}", i.0, i.1);
match i.1.opcode {
LoadInt => print!("({})", static_data.constpool.intpool[i.1.operand]),
LoadString => print!("({})", static_data.constpool.stringpool[i.1.operand]),
LoadFloat => print!("({})", static_data.constpool.floatpool[i.1.operand]),
_ => {}
}
println!();
Expand Down
1 change: 1 addition & 0 deletions src/tvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,7 @@ impl<'a> Vm<'a> {
let condit = impl_opcode!(bool, self, 1);
if !condit {
*pc = self.static_data.inst[*pc].operand;
return Ok(());
}
}
Opcode::Jump => {
Expand Down

0 comments on commit 6a57882

Please sign in to comment.