mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			244 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			244 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| # This file is part of NIT ( http://www.nitlanguage.org ).
 | |
| #
 | |
| # Copyright 2012-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.
 | |
| 
 | |
| # Draws an arithmetic operation to the terminal
 | |
| module draw_operation
 | |
| 
 | |
| redef enum Int
 | |
| 	fun n_chars: Int `{
 | |
| 		int c;
 | |
| 		if ( abs(recv) >= 10 )
 | |
| 			c = 1+(int)log10f( (float)abs(recv) );
 | |
| 		else
 | |
| 			c = 1;
 | |
| 		if ( recv < 0 ) c ++;
 | |
| 		return c;
 | |
| 	`}
 | |
| end
 | |
| 
 | |
| redef enum Char
 | |
| 	fun as_operator(a, b: Int): Int
 | |
| 	do
 | |
| 		if self == '+' then return a + b
 | |
| 		if self == '-' then return a - b
 | |
| 		if self == '*' then return a * b
 | |
| 		if self == '/' then return a / b
 | |
| 		if self == '%' then return a % b
 | |
| 		abort
 | |
| 	end
 | |
| 
 | |
| 	fun override_dispc: Bool
 | |
| 	do
 | |
| 		return self == '+' or self == '-' or self == '*' or self == '/' or self == '%'
 | |
| 	end
 | |
| 
 | |
| 	fun lines(s: Int): Array[Line]
 | |
| 	do
 | |
| 		if self == '+' then
 | |
| 			return [new Line(new P(0,s/2),1,0,s), new Line(new P(s/2,1),0,1,s-2)]
 | |
| 		else if self == '-' then
 | |
| 			return [new Line(new P(0,s/2),1,0,s)]
 | |
| 		else if self == '*' then
 | |
| 			var lines = new Array[Line]
 | |
| 			for y in [1..s-1[ do
 | |
| 				lines.add( new Line(new P(1,y), 1,0,s-2) )
 | |
| 			end
 | |
| 			return lines
 | |
| 		else if self == '/' then
 | |
| 			return [new Line(new P(s-1,0), -1,1, s )]
 | |
| 		else if self == '%' then
 | |
| 			var q4 = s/4
 | |
| 			var lines = [new Line(new P(s-1,0),-1,1,s)]
 | |
| 			for l in [0..q4[ do
 | |
| 				lines.append([ new Line( new P(0,l), 1,0,q4), new Line( new P(s-1,s-1-l), -1,0,q4) ])
 | |
| 			end
 | |
| 			return lines
 | |
| 		else if self == '1' then
 | |
| 			return [new Line(new P(s/2,0), 0,1,s),new Line(new P(0,s-1),1,0,s),
 | |
| 				new Line( new P(s/2,0),-1,1,s/2)]
 | |
| 		else if self == '2' then
 | |
| 			return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,0),0,1,s/2),
 | |
| 				new Line( new P(0,s-1),1,0,s), new Line( new P(0,s/2), 0,1,s/2),
 | |
| 				new Line( new P(0,s/2), 1,0,s)]
 | |
| 		else if self == '3' then
 | |
| 			return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,0),0,1,s),
 | |
| 				new Line( new P(0,s-1),1,0,s), new Line( new P(0,s/2), 1,0,s)]
 | |
| 		else if self == '4' then
 | |
| 			return [new Line(new P(s-1,0),0,1,s), new Line( new P(0,0), 0,1,s/2),
 | |
| 				new Line( new P(0,s/2), 1,0,s)]
 | |
| 		else if self == '5' then
 | |
| 			return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,s/2),0,1,s/2),
 | |
| 				new Line( new P(0,s-1),1,0,s), new Line( new P(0,0), 0,1,s/2),
 | |
| 				new Line( new P(0,s/2), 1,0,s)]
 | |
| 		else if self == '6' then
 | |
| 			return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,s/2),0,1,s/2),
 | |
| 				new Line( new P(0,s-1),1,0,s), new Line( new P(0,0), 0,1,s),
 | |
| 				new Line( new P(0,s/2), 1,0,s)]
 | |
| 		else if self == '7' then
 | |
| 			var tl = new P(0,0)
 | |
| 			var tr = new P(s-1,0)
 | |
| 			return [new Line(tl, 1,0,s), new Line(tr,-1,1,s)]
 | |
| 		else if self == '8' then
 | |
| 			return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,0),0,1,s),
 | |
| 				new Line( new P(0,s-1),1,0,s), new Line( new P(0,0), 0,1,s),
 | |
| 				new Line( new P(0,s/2), 1,0,s)]
 | |
| 		else if self == '9' then
 | |
| 			return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,0),0,1,s),
 | |
| 				new Line( new P(0,s-1),1,0,s), new Line( new P(0,0), 0,1,s/2),
 | |
| 				new Line( new P(0,s/2), 1,0,s)]
 | |
| 		else if self == '0' then
 | |
| 			return [new Line(new P(0,0), 1,0,s),new Line(new P(s-1,0),0,1,s),
 | |
| 				new Line( new P(0,s-1),1,0,s), new Line( new P(0,0), 0,1,s)]
 | |
| 		end
 | |
| 		return new Array[Line]
 | |
| 	end
 | |
| end
 | |
| 
 | |
| class P
 | |
| 	var x : Int
 | |
| 	var y : Int
 | |
| end
 | |
| 
 | |
| redef class String
 | |
| 	# hack is to support a bug in the evaluation software
 | |
| 	fun draw(dispc: Char, size, gap: Int, hack: Bool)
 | |
| 	do
 | |
| 		var w = size * length +(length-1)*gap
 | |
| 		var h = size
 | |
| 		var map = new Array[Array[Char]]
 | |
| 		for x in [0..w[ do
 | |
| 			map[x] = new Array[Char].filled_with( ' ',  h )
 | |
| 		end
 | |
| 
 | |
| 		var ci = 0
 | |
| 		for c in self.chars do
 | |
| 			var local_dispc
 | |
| 			if c.override_dispc then
 | |
| 				local_dispc = c
 | |
| 			else
 | |
| 				local_dispc = dispc
 | |
| 			end
 | |
| 
 | |
| 			var lines = c.lines( size )
 | |
| 			for line in lines do
 | |
| 				var x = line.o.x+ci*size
 | |
| 					x += ci*gap
 | |
| 				var y = line.o.y
 | |
| 				for s in [0..line.len[ do
 | |
| 					assert map.length > x and map[x].length > y else print "setting {x},{y} as {local_dispc}"
 | |
| 					map[x][y] = local_dispc
 | |
| 					x += line.step_x
 | |
| 					y += line.step_y
 | |
| 				end
 | |
| 			end
 | |
| 
 | |
| 			ci += 1
 | |
| 		end
 | |
| 
 | |
| 		if hack then
 | |
| 			for c in [0..size[ do
 | |
| 				map[c][0] = map[map.length-size+c][0]
 | |
| 				map[map.length-size+c][0] = ' '
 | |
| 			end
 | |
| 		end
 | |
| 
 | |
| 		for y in [0..h[ do
 | |
| 			for x in [0..w[ do
 | |
| 				printn map[x][y]
 | |
| 			end
 | |
| 			print ""
 | |
| 		end
 | |
| 	end
 | |
| end
 | |
| 
 | |
| class Line
 | |
| 	var o : P
 | |
| 	var step_x : Int
 | |
| 	var step_y : Int
 | |
| 	var len : Int
 | |
| end
 | |
| 
 | |
| var a
 | |
| var b
 | |
| var op_char
 | |
| var disp_char
 | |
| var disp_size
 | |
| var disp_gap
 | |
| 
 | |
| if "NIT_TESTING".environ == "true" then
 | |
| 	a = 567
 | |
| 	b = 13
 | |
| 	op_char = '*'
 | |
| 	disp_char = 'O'
 | |
| 	disp_size = 8
 | |
| 	disp_gap = 1
 | |
| else
 | |
| 	printn "Left operand: "
 | |
| 	a = gets.to_i
 | |
| 
 | |
| 	printn "Right operand: "
 | |
| 	b = gets.to_i
 | |
| 
 | |
| 	printn "Operator (+, -, *, /, %): "
 | |
| 	op_char = gets.chars[0]
 | |
| 
 | |
| 	printn "Char to display: "
 | |
| 	disp_char = gets.chars[0]
 | |
| 
 | |
| 	printn "Size of text: "
 | |
| 	disp_size = gets.to_i
 | |
| 
 | |
| 	printn "Space between digits: "
 | |
| 	disp_gap = gets.to_i
 | |
| end
 | |
| 
 | |
| var result = op_char.as_operator( a, b )
 | |
| 
 | |
| var len_a = a.n_chars
 | |
| var len_b = b.n_chars
 | |
| var len_res = result.n_chars
 | |
| var max_len = len_a.max( len_b.max( len_res ) ) + 1
 | |
| 
 | |
| # draw first line
 | |
| var d = max_len - len_a
 | |
| var line_a = ""
 | |
| for i in [0..d[ do line_a += " "
 | |
| line_a += a.to_s
 | |
| line_a.draw( disp_char, disp_size, disp_gap, false )
 | |
| 
 | |
| print ""
 | |
| # draw second line
 | |
| d = max_len - len_b-1
 | |
| var line_b = op_char.to_s
 | |
| for i in [0..d[ do line_b += " "
 | |
| line_b += b.to_s
 | |
| line_b.draw( disp_char, disp_size, disp_gap, false )
 | |
| 
 | |
| # draw -----
 | |
| print ""
 | |
| for i in [0..disp_size*max_len+(max_len-1)*disp_gap] do
 | |
| 	printn "_"
 | |
| end
 | |
| print ""
 | |
| print ""
 | |
| 
 | |
| # draw result
 | |
| d = max_len - len_res
 | |
| var line_res = ""
 | |
| for i in [0..d[ do line_res += " "
 | |
| line_res += result.to_s
 | |
| line_res.draw( disp_char, disp_size, disp_gap, false )
 |