examples: vfmt calculator.v

pull/6199/head
Charadon 2020-08-23 14:18:37 +00:00 committed by GitHub
parent 1c9e02094c
commit bb60b4227e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 135 additions and 134 deletions

View File

@ -1,10 +1,9 @@
// Q: What's this? // Q: What's this?
// A: This is a mini "home-made" calculator. You may also regard it as a very elementary version of "interpreter". // A: This is a mini "home-made" calculator. You may also regard it as a very elementary version of "interpreter".
import os import os
const ( const (
numeric_char = [`0`,`1`,`2`,`3`,`4`,`5`,`6`,`7`,`8`,`9`,`.`,`e`,`E`] numeric_char = [`0`, `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `.`, `e`, `E`]
) )
// Convert expression to Reverse Polish Notation. // Convert expression to Reverse Polish Notation.
@ -15,53 +14,52 @@ fn expr_to_rev_pol(expr string) ?[]string {
mut stack := []string{} mut stack := []string{}
mut rev_pol := []string{} mut rev_pol := []string{}
mut pos := 0 mut pos := 0
for pos<expr.len { for pos < expr.len {
mut end_pos := pos mut end_pos := pos
for end_pos<expr.len && expr[end_pos] in numeric_char { for end_pos < expr.len && expr[end_pos] in numeric_char {
end_pos++ end_pos++
} }
if end_pos>pos { if end_pos > pos {
stack << expr[pos..end_pos] stack << expr[pos..end_pos]
pos = end_pos pos = end_pos
} } else if end_pos == pos {
else if end_pos==pos {
op := expr[pos].str() op := expr[pos].str()
match op { match op {
'(' { '(' {
stack << op stack << op
} }
'*', '/' { '*', '/' {
for stack.len>0 && stack.last() !in ['(', '+', '-'] { for stack.len > 0 && stack.last() !in ['(', '+', '-'] {
rev_pol << stack.last() rev_pol << stack.last()
stack.delete(stack.len-1) stack.delete(stack.len - 1)
} }
stack << op stack << op
} }
'+', '-' { '+', '-' {
for stack.len>0 && stack.last() != '(' { for stack.len > 0 && stack.last() != '(' {
rev_pol << stack.last() rev_pol << stack.last()
stack.delete(stack.len-1) stack.delete(stack.len - 1)
} }
stack << op stack << op
} }
')' { ')' {
for stack.len>0 && stack.last() != '(' { for stack.len > 0 && stack.last() != '(' {
rev_pol << stack.last() rev_pol << stack.last()
stack.delete(stack.len-1) stack.delete(stack.len - 1)
} }
stack.delete(stack.len-1) stack.delete(stack.len - 1)
} }
else { else {
return error('err: invalid character `${op}`') return error('err: invalid character `$op`')
} }
} }
pos++ pos++
} }
} }
for stack.len>0 { for stack.len > 0 {
top := stack.last() top := stack.last()
rev_pol << top rev_pol << top
stack.delete(stack.len-1) stack.delete(stack.len - 1)
} }
return rev_pol return rev_pol
} }
@ -72,27 +70,31 @@ fn eval_rev_pol(rev_pol []string) ?f64 {
for item in rev_pol { for item in rev_pol {
if is_num_string(item) { if is_num_string(item) {
stack << item.f64() stack << item.f64()
} } else {
else { if stack.len >= 2 {
if stack.len>=2 {
oprand_r := stack.last() oprand_r := stack.last()
stack.delete(stack.len-1) stack.delete(stack.len - 1)
oprand_l := stack.last() oprand_l := stack.last()
stack.delete(stack.len-1) stack.delete(stack.len - 1)
match item { match item {
'+' { stack << oprand_l+oprand_r } '+' {
'-' { stack << oprand_l-oprand_r } stack << oprand_l + oprand_r
'*' { stack << oprand_l*oprand_r } }
'-' {
stack << oprand_l - oprand_r
}
'*' {
stack << oprand_l * oprand_r
}
'/' { '/' {
if oprand_r == 0 { if oprand_r == 0 {
return error('err: divide by zero') return error('err: divide by zero')
} }
stack << oprand_l/oprand_r stack << oprand_l / oprand_r
} }
else {} else {}
} }
} } else {
else {
return error('err: invalid expression') return error('err: invalid expression')
} }
} }
@ -109,10 +111,9 @@ fn is_num_string(str string) bool {
return true return true
} }
fn main() { fn main() {
println('Please enter the expression you want to calculate, e.g. 1e2+(3-2.5)*6/1.5 .') println('Please enter the expression you want to calculate, e.g. 1e2+(3-2.5)*6/1.5 .')
println('Enter \'exit\' or \'EXIT\' to quit.') println("Enter \'exit\' or \'EXIT\' to quit.")
mut expr_count := 0 mut expr_count := 0
for { for {
expr_count++ expr_count++