1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
(* Orpie -- a stack-based RPN calculator for the console
* Copyright (C) 2003-2004 Paul Pelzl
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Please send bug reports, patches, etc. to Paul Pelzl at
* <pelzlpj@eecs.umich.edu>.
*)
open Curses;;
open Rpc_calc;;
open Operations;;
open Complex;;
exception Not_handled;;
(* help_win is provided as an option, because it may be dropped if
* the screen width is too small *)
type screen_t = {stdscr:window; mutable lines:int; mutable cols:int;
mutable help_win:window option; mutable hw_lines:int; mutable hw_cols:int;
mutable stack_win:window; mutable sw_lines:int; mutable sw_cols:int;
mutable entry_win:window; mutable ew_lines:int; mutable ew_cols:int};;
type help_mode_t = | StandardHelp | StandardIntHelp | AbbrevHelp | VarHelp;;
type entry_t = | IntEntry | FloatEntry | ComplexEntry
| FloatMatrixEntry | ComplexMatrixEntry | VarEntry;;
type interface_mode_t = | StandardEntryMode | IntEditMode | AbbrevEntryMode
| VarEditMode | BrowsingMode | UnitEditMode;;
type complex_entry_element_t =
{mutable re_mantissa : string; mutable re_exponent : string;
mutable im_mantissa : string; mutable im_exponent : string;
mutable is_polar : bool};;
let max_matrix_size = 1000;;
let all_taglines = [| "RPN for the masses";
"'=' is for the weak";
"swap drop dup view";
"I hate the mouse";
"now w/ 800% more stack";
"powered by Ocaml";
"compute _this_";
"interface as art";
"kick that data's ass";
"Nice.";
"configurability is key";
":wq";
"the \"Mutt\" of calcs"|];
(* everything you need to know about the interface state goes in this variable *)
type interface_state_t =
{version : string; (* program version string *)
tagline : string;
calc : rpc_calc;
mutable scr : screen_t; (* curses screen with two or three subwindows *)
mutable run_calc : bool; (* exit when run_true becomes false *)
mutable stack_bottom_row : int; (* controls what portion of the stack is viewable *)
mutable stack_selection : int; (* in stack browsing mode, this item is selected *)
mutable interface_mode : interface_mode_t; (* standard mode or stack browsing mode *)
mutable horiz_scroll : int; (* controls how far an element is scrolled left/right *)
mutable help_mode : help_mode_t; (* controls the mode of context-sensitive help *)
mutable help_page : int; (* which help page is being viewed *)
mutable has_entry : bool; (* whether or not the entry buffer has anything in it *)
mutable entry_type : entry_t; (* the current type of data being entered *)
mutable int_entry_buffer : string; (* holds characters entered for int data type *)
mutable is_entering_base : bool; (* is the user is entering a base *)
mutable int_base_string : string; (* one-character representation of the base *)
mutable is_entering_exponent : bool; (* is the user entering a scientific notation exponent *)
mutable abbrev_entry_buffer : string; (* stores characters entered in abbrev entry mode *)
mutable matched_abbrev_entry : string; (* stores the command-completed abbrev entry *)
mutable matched_abbrev_entry_list : string list; (* stores the list of all possible command completions *)
gen_buffer : complex_entry_element_t array; (* storage for floating-point (array)-based types *)
mutable variable_entry_buffer : string; (* stores characters entered in variable entry mode *)
mutable variable_entry_buffer_back : string; (* used in variable completion *)
mutable matched_variables : string list; (* stores the list of all matching variable completions *)
mutable sorted_variables : string list; (* stores an alphabetically sorted list of all variables *)
mutable completion : int option; (* which one of the list elements to complete variables with *)
mutable curr_buf : int; (* which element of gen_buffer is being edited *)
mutable is_entering_imag : bool; (* is the imaginary component being edited *)
mutable matrix_cols : int; (* how many cols in the matrix being entered *)
mutable has_multiple_rows : bool; (* does the matrix being entered have >1 row *)
mutable units_entry_buffer : string; (* stores unit characters entered *)
mutable is_entering_units : bool} (* is the user appending units *)
(* create and initialize an interface with default settings *)
let make (c : rpc_calc) (std : screen_t) =
Random.self_init ();
let tagline_index = Random.int (Array.length all_taglines) in
let iface = {
version = Version.version;
tagline = all_taglines.(tagline_index);
calc = c;
scr = std;
run_calc = true;
stack_bottom_row = 1;
stack_selection = 1;
interface_mode = StandardEntryMode;
horiz_scroll = 0;
help_mode = StandardHelp;
help_page = 0;
has_entry = false;
entry_type = FloatEntry;
int_entry_buffer = "";
is_entering_base = false;
int_base_string = "";
is_entering_exponent = false;
abbrev_entry_buffer = "";
matched_abbrev_entry = "";
matched_abbrev_entry_list = [];
variable_entry_buffer = "";
variable_entry_buffer_back = "";
matched_variables = [];
sorted_variables = [];
completion = None;
gen_buffer = Array.make max_matrix_size
{re_mantissa = ""; re_exponent = "";
im_mantissa = ""; im_exponent = ""; is_polar = false};
curr_buf = 0;
is_entering_imag = false;
matrix_cols = 1;
has_multiple_rows = false;
units_entry_buffer = "";
is_entering_units = false
} in
iface
(* arch-tag: DO_NOT_CHANGE_2e912989-cdb2-498a-9bb3-b6d76e94f3a5 *)
|