mirror of
https://github.com/KevinMidboe/linguist.git
synced 2026-01-14 21:35:53 +00:00
Added examples for Nit to samples.
Signed-off-by: Lucas Bajolet <r4pass@hotmail.com>
This commit is contained in:
272
samples/Nit/calculator.nit
Normal file
272
samples/Nit/calculator.nit
Normal file
@@ -0,0 +1,272 @@
|
||||
# This file is part of NIT ( http://www.nitlanguage.org ).
|
||||
#
|
||||
# Copyright 2013 Alexis Laferrière <alexis.laf@xymus.net>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import gtk
|
||||
|
||||
class CalculatorContext
|
||||
var result : nullable Float = null
|
||||
|
||||
var last_op : nullable Char = null
|
||||
|
||||
var current : nullable Float = null
|
||||
var after_point : nullable Int = null
|
||||
|
||||
fun push_op( op : Char )
|
||||
do
|
||||
apply_last_op_if_any
|
||||
if op == 'C' then
|
||||
self.result = 0.0
|
||||
last_op = null
|
||||
else
|
||||
last_op = op # store for next push_op
|
||||
end
|
||||
|
||||
# prepare next current
|
||||
after_point = null
|
||||
current = null
|
||||
end
|
||||
|
||||
fun push_digit( digit : Int )
|
||||
do
|
||||
var current = current
|
||||
if current == null then current = 0.0
|
||||
|
||||
var after_point = after_point
|
||||
if after_point == null then
|
||||
current = current * 10.0 + digit.to_f
|
||||
else
|
||||
current = current + digit.to_f * 10.0.pow(after_point.to_f)
|
||||
self.after_point -= 1
|
||||
end
|
||||
|
||||
self.current = current
|
||||
end
|
||||
|
||||
fun switch_to_decimals
|
||||
do
|
||||
if self.current == null then current = 0.0
|
||||
if after_point != null then return
|
||||
|
||||
after_point = -1
|
||||
end
|
||||
|
||||
fun apply_last_op_if_any
|
||||
do
|
||||
var op = last_op
|
||||
|
||||
var result = result
|
||||
if result == null then result = 0.0
|
||||
|
||||
var current = current
|
||||
if current == null then current = 0.0
|
||||
|
||||
if op == null then
|
||||
result = current
|
||||
else if op == '+' then
|
||||
result = result + current
|
||||
else if op == '-' then
|
||||
result = result - current
|
||||
else if op == '/' then
|
||||
result = result / current
|
||||
else if op == '*' then
|
||||
result = result * current
|
||||
end
|
||||
self.result = result
|
||||
self.current = null
|
||||
end
|
||||
end
|
||||
|
||||
class CalculatorGui
|
||||
super GtkCallable
|
||||
|
||||
var win : GtkWindow
|
||||
var container : GtkGrid
|
||||
|
||||
var lbl_disp : GtkLabel
|
||||
var but_eq : GtkButton
|
||||
var but_dot : GtkButton
|
||||
|
||||
var context = new CalculatorContext
|
||||
|
||||
redef fun signal( sender, user_data )
|
||||
do
|
||||
var after_point = context.after_point
|
||||
if after_point == null then
|
||||
after_point = 0
|
||||
else
|
||||
after_point = (after_point.abs)
|
||||
end
|
||||
|
||||
if user_data isa Char then # is an operation
|
||||
var c = user_data
|
||||
if c == '.' then
|
||||
but_dot.sensitive= false
|
||||
context.switch_to_decimals
|
||||
lbl_disp.text = "{context.current.to_i}."
|
||||
else
|
||||
but_dot.sensitive= true
|
||||
context.push_op( c )
|
||||
|
||||
var s = context.result.to_precision_native(6)
|
||||
var index : nullable Int = null
|
||||
for i in s.length.times do
|
||||
var chiffre = s.chars[i]
|
||||
if chiffre == '0' and index == null then
|
||||
index = i
|
||||
else if chiffre != '0' then
|
||||
index = null
|
||||
end
|
||||
end
|
||||
if index != null then
|
||||
s = s.substring(0, index)
|
||||
if s.chars[s.length-1] == ',' then s = s.substring(0, s.length-1)
|
||||
end
|
||||
lbl_disp.text = s
|
||||
end
|
||||
else if user_data isa Int then # is a number
|
||||
var n = user_data
|
||||
context.push_digit( n )
|
||||
lbl_disp.text = context.current.to_precision_native(after_point)
|
||||
end
|
||||
end
|
||||
|
||||
init
|
||||
do
|
||||
init_gtk
|
||||
|
||||
win = new GtkWindow( 0 )
|
||||
|
||||
container = new GtkGrid(5,5,true)
|
||||
win.add( container )
|
||||
|
||||
lbl_disp = new GtkLabel( "_" )
|
||||
container.attach( lbl_disp, 0, 0, 5, 1 )
|
||||
|
||||
# digits
|
||||
for n in [0..9] do
|
||||
var but = new GtkButton.with_label( n.to_s )
|
||||
but.request_size( 64, 64 )
|
||||
but.signal_connect( "clicked", self, n )
|
||||
if n == 0 then
|
||||
container.attach( but, 0, 4, 1, 1 )
|
||||
else container.attach( but, (n-1)%3, 3-(n-1)/3, 1, 1 )
|
||||
end
|
||||
|
||||
# operators
|
||||
var r = 1
|
||||
for op in ['+', '-', '*', '/' ] do
|
||||
var but = new GtkButton.with_label( op.to_s )
|
||||
but.request_size( 64, 64 )
|
||||
but.signal_connect( "clicked", self, op )
|
||||
container.attach( but, 3, r, 1, 1 )
|
||||
r+=1
|
||||
end
|
||||
|
||||
# =
|
||||
but_eq = new GtkButton.with_label( "=" )
|
||||
but_eq.request_size( 64, 64 )
|
||||
but_eq.signal_connect( "clicked", self, '=' )
|
||||
container.attach( but_eq, 4, 3, 1, 2 )
|
||||
|
||||
# .
|
||||
but_dot = new GtkButton.with_label( "." )
|
||||
but_dot.request_size( 64, 64 )
|
||||
but_dot.signal_connect( "clicked", self, '.' )
|
||||
container.attach( but_dot, 1, 4, 1, 1 )
|
||||
|
||||
#C
|
||||
var but_c = new GtkButton.with_label( "C" )
|
||||
but_c.request_size( 64, 64 )
|
||||
but_c.signal_connect("clicked", self, 'C')
|
||||
container.attach( but_c, 2, 4, 1, 1 )
|
||||
|
||||
win.show_all
|
||||
end
|
||||
end
|
||||
|
||||
# context tests
|
||||
var context = new CalculatorContext
|
||||
context.push_digit( 1 )
|
||||
context.push_digit( 2 )
|
||||
context.push_op( '+' )
|
||||
context.push_digit( 3 )
|
||||
context.push_op( '*' )
|
||||
context.push_digit( 2 )
|
||||
context.push_op( '=' )
|
||||
var r = context.result.to_precision( 2 )
|
||||
assert r == "30.00" else print r
|
||||
|
||||
context = new CalculatorContext
|
||||
context.push_digit( 1 )
|
||||
context.push_digit( 4 )
|
||||
context.switch_to_decimals
|
||||
context.push_digit( 1 )
|
||||
context.push_op( '*' )
|
||||
context.push_digit( 3 )
|
||||
context.push_op( '=' )
|
||||
r = context.result.to_precision( 2 )
|
||||
assert r == "42.30" else print r
|
||||
|
||||
context.push_op( '+' )
|
||||
context.push_digit( 1 )
|
||||
context.push_digit( 1 )
|
||||
context.push_op( '=' )
|
||||
r = context.result.to_precision( 2 )
|
||||
assert r == "53.30" else print r
|
||||
|
||||
context = new CalculatorContext
|
||||
context.push_digit( 4 )
|
||||
context.push_digit( 2 )
|
||||
context.switch_to_decimals
|
||||
context.push_digit( 3 )
|
||||
context.push_op( '/' )
|
||||
context.push_digit( 3 )
|
||||
context.push_op( '=' )
|
||||
r = context.result.to_precision( 2 )
|
||||
assert r == "14.10" else print r
|
||||
|
||||
#test multiple decimals
|
||||
context = new CalculatorContext
|
||||
context.push_digit( 5 )
|
||||
context.push_digit( 0 )
|
||||
context.switch_to_decimals
|
||||
context.push_digit( 1 )
|
||||
context.push_digit( 2 )
|
||||
context.push_digit( 3 )
|
||||
context.push_op( '+' )
|
||||
context.push_digit( 1 )
|
||||
context.push_op( '=' )
|
||||
r = context.result.to_precision( 3 )
|
||||
assert r == "51.123" else print r
|
||||
|
||||
#test 'C' button
|
||||
context = new CalculatorContext
|
||||
context.push_digit( 1 )
|
||||
context.push_digit( 0 )
|
||||
context.push_op( '+' )
|
||||
context.push_digit( 1 )
|
||||
context.push_digit( 0 )
|
||||
context.push_op( '=' )
|
||||
context.push_op( 'C' )
|
||||
r = context.result.to_precision( 1 )
|
||||
assert r == "0.0" else print r
|
||||
|
||||
# graphical application
|
||||
|
||||
if "NIT_TESTING".environ != "true" then
|
||||
var app = new CalculatorGui
|
||||
run_gtk
|
||||
end
|
||||
Reference in New Issue
Block a user