Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 119 additions & 0 deletions dana/programs/calculator.dana
Original file line number Diff line number Diff line change
@@ -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:
<Num1> <Op> <Num2>
where <NumX> is a positive integer
and <Op> 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

11 changes: 11 additions & 0 deletions dana/programs/calculator.input
Original file line number Diff line number Diff line change
@@ -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
11 changes: 11 additions & 0 deletions dana/programs/calculator.output
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
3
1
10
25
35
30
3
Invalid
Invalid
Invalid
Invalid