diff --git a/dana/programs/calculator.dana b/dana/programs/calculator.dana new file mode 100644 index 0000000..2ba3c6d --- /dev/null +++ b/dana/programs/calculator.dana @@ -0,0 +1,119 @@ +def main + # Helper Function + + def is_digit is byte: c as byte + if '0' <= c and c <= '9': return: true + else: return: false + + def is_operator is byte: c as byte + if c = '+' or c = '-' or c = '*' or c = '/': + return: true + else: + return false + + (* + Conversion from part of a string to an int + [from, to) + *) + def string_to_int is int: s as byte[], from to as int + var i res pow is int + + res := 0 + pow := 1 + + i := to - 1 + loop: + if i < from: break + res := res + pow * extend(s[i] - '0') + pow := pow * 10 + i := i - 1 + + return: res + + (* + Simple Calculator + + Input: lines of the following form: + + where is a positive integer + and is one of +, -, *, / + Any other characters among them get ignored. + + Output: lines with the results + or a message "Invalid" in case of failure + *) + + var buf is byte[256] + var idx len start end a b is int + var op is byte + + loop lines: + readString: 256, buf + + # Stop if we got nothing + len := strlen(buf) + if len = 0: break: lines + + idx := 0 + + loop a_start: + if idx == len: + writeString: "Invalid\n" + continue: lines + elif is_number(buf[idx]): + break: a_start + idx := idx + 1 + start := idx; + + loop a_end: + if idx == len: + writeString: "Invalid\n" + continue: lines + elif not is_number(buf[idx]): + break: a_end + idx := idx + 1 + end := idx; + + a := string_to_int(buff, start, end); + + loop op_detect: + if idx == len: + writeString: "Invalid\n" + continue: lines + elif is_operator(buf[idx]): + break: op_detect + idx := idx + 1 + op := buf[idx] + + loop b_start: + if idx == len: + writeString: "Invalid\n" + continue: lines + elif is_number(buf[idx]): + break: b_start + idx := idx + 1 + start := idx; + + loop b_end: + if idx == len or not is_number(buf[idx]): + break: b_end + idx := idx + 1 + end := idx; + + b := string_to_int(buff, start, end); + + # We have finished parsing now we can calculate + + if op = '+': + writeInteger: a + b + elif op = '-': + writeInteger: a - b + elif op = '*': + writeInteger: a * b + elif op = '/': + writeInteger: a / b + else: + writeString: "Invalid\n" + + exit + diff --git a/dana/programs/calculator.input b/dana/programs/calculator.input new file mode 100644 index 0000000..e6168cc --- /dev/null +++ b/dana/programs/calculator.input @@ -0,0 +1,11 @@ +1+2 +4-3 +5*2 +100/4 +25 + 10 + 10 * 3 dsfdfadf +asdf 5sdf -adfd2 +5- +35+ ++7 +2345 _ 2342 diff --git a/dana/programs/calculator.output b/dana/programs/calculator.output new file mode 100644 index 0000000..5e662a4 --- /dev/null +++ b/dana/programs/calculator.output @@ -0,0 +1,11 @@ +3 +1 +10 +25 +35 +30 +3 +Invalid +Invalid +Invalid +Invalid