ugBASIC 1.18
An isomorphic BASIC language compiler for retrocomputers
Loading...
Searching...
No Matches
input.c
Go to the documentation of this file.
1/*****************************************************************************
2 * ugBASIC - an isomorphic BASIC language compiler for retrocomputers *
3 *****************************************************************************
4 * Copyright 2021-2026 Marco Spedaletti (asimov@mclink.it)
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *----------------------------------------------------------------------------
18 * Concesso in licenza secondo i termini della Licenza Apache, versione 2.0
19 * (la "Licenza"); è proibito usare questo file se non in conformità alla
20 * Licenza. Una copia della Licenza è disponibile all'indirizzo:
21 *
22 * http://www.apache.org/licenses/LICENSE-2.0
23 *
24 * Se non richiesto dalla legislazione vigente o concordato per iscritto,
25 * il software distribuito nei termini della Licenza è distribuito
26 * "COSÌ COM'È", SENZA GARANZIE O CONDIZIONI DI ALCUN TIPO, esplicite o
27 * implicite. Consultare la Licenza per il testo specifico che regola le
28 * autorizzazioni e le limitazioni previste dalla medesima.
29 ****************************************************************************/
30
31/****************************************************************************
32 * INCLUDE SECTION
33 ****************************************************************************/
34
35#include "../../../ugbc.h"
36
37/****************************************************************************
38 * CODE SECTION
39 ****************************************************************************/
40
41#if defined(__c128__) || defined(__c64__) || defined(__c64reu__)
42
43extern char DATATYPE_AS_STRING[][16];
44
45
46/* <usermanual>
47@keyword INPUT (function)
48
49@english
50
51The ''INPUT'' command allows you to ask the user to enter data, such as
52numbers or text, while your program is running. When your program
53encounters an ''INPUT'' statement, it stops executing and displays
54a prompt (usually the name of the variable) that invites the user
55to enter a value. The user types the value and presses Enter.
56The entered value is then stored in the specified variable.
57
58Make sure the variable type matches the type of data you want
59to capture (e.g. a numeric variable for a number, a string
60variable for text). The message is optional but highly
61recommended to make it clear to the user what to enter.
62After entering the value, the user must always press Enter to confirm.
63
64@italian
65
66Il comando ''INPUT'' consente di chiedere all'utente di immettere dati,
67come numeri o testo, mentre il programma è in esecuzione. Quando il
68programma incontra un'istruzione ''INPUT'', interrompe l'esecuzione e
69visualizza un prompt (solitamente il nome della variabile) che invita
70l'utente a immettere un valore. L'utente digita il valore e preme Invio.
71Il valore immesso viene quindi memorizzato nella variabile specificata.
72
73Assicurati che il tipo di variabile corrisponda al tipo di dati che
74desideri acquisire (ad esempio una variabile numerica per un numero,
75una variabile stringa per il testo). Il messaggio è facoltativo ma
76altamente consigliato per chiarire all'utente cosa immettere.
77Dopo aver immesso il valore, l'utente deve sempre premere
78invio per confermare.
79
80@syntax INPUT [prompt];v1[;v2[;...]
81@syntax INPUT [prompt];v1[,v2[,...]
82@syntax INPUT [prompt],v1[;v2[;...]
83@syntax INPUT [prompt],v1[,v2[,...]
84
85@example INPUT "Type a string ", a$
86@example PRINT "The string was "; a$
87
88@seeAlso INPUT (function)
89
90</usermanual> */
91
92/* <usermanual>
93@keyword LINE INPUT
94
95@english
96
97The ''LINE INPUT'' command takes a complete line of text entered
98by the user and assign it to a string variable. Unlike the ''INPUT''
99command, which stops at the first comma or space, ''LINE INPUT''
100reads all the characters until the user presses enter.
101
102Typically, you precede the ''LINE INPUT'' command with a message
103that tells the user what to enter. When the user presses enter,
104the entire line of text typed is assigned to the variable specified
105after the ''LINE INPUT'' command.
106
107The variable containing the captured string can be used later in
108the program for various operations, such as printing the value,
109comparing it to other strings, or manipulating it further.
110
111The ''LINE INPUT'' is especially useful when you want to capture
112sentences or longer texts, which may contain spaces, commas, and
113other special characters. It does not impose restrictions on the
114format of the input, allowing the user to enter any type of
115character. It is a command that is easy to use and understand.
116
117@italian
118
119Il comando ''LINE INPUT'' prende una riga completa di testo
120immessa dall'utente e la assegna a una variabile stringa. A
121differenza del comando ''INPUT'', che si ferma alla prima virgola
122o spazio, ''LINE INPUT'' legge tutti i caratteri finché l'utente
123 non preme Invio.
124
125In genere, si fa precedere il comando ''LINE INPUT'' da un messaggio
126che indica all'utente cosa immettere. Quando l'utente preme Invio,
127l'intera riga di testo digitata viene assegnata alla variabile
128specificata dopo il comando ''LINE INPUT''.
129
130La variabile contenente la stringa catturata può essere utilizzata
131in seguito nel programma per varie operazioni, come la stampa del
132valore, il confronto con altre stringhe o l'ulteriore manipolazione.
133
134''LINE INPUT'' è particolarmente utile quando si desidera catturare
135frasi o testi più lunghi, che possono contenere spazi, virgole e
136altri caratteri speciali. Non impone restrizioni al formato
137dell'input, consentendo all'utente di immettere qualsiasi tipo
138di carattere. È un comando facile da usare e da capire.
139
140@syntax LINE INPUT [prompt];v1
141@syntax LINE INPUT [prompt],v1
142
143@example LINE INPUT "Type a line ", a$
144@example PRINT a$
145
146@seeAlso INPUT (instruction)
147
148</usermanual> */
149
150void input( Environment * _environment, char * _variable, VariableType _default_type ) {
151
153
154 Variable * result;
155 if ( variable_exists( _environment, _variable ) ) {
156 result = variable_retrieve( _environment, _variable );
157 } else {
158 result = variable_define( _environment, _variable, _default_type, 0 );
159 }
160
161 char repeatLabel[MAX_TEMPORARY_STORAGE]; sprintf(repeatLabel, "%srepeat", label );
162 char finishedLabel[MAX_TEMPORARY_STORAGE]; sprintf(finishedLabel, "%sfinished", label );
163 char doneLabel[MAX_TEMPORARY_STORAGE]; sprintf(doneLabel, "%sdone", label );
164 char backspaceLabel[MAX_TEMPORARY_STORAGE]; sprintf(backspaceLabel, "%sbackspace", label );
165
166 Variable * temporary = variable_temporary( _environment, VT_DSTRING, "(temporary storage for input)");
167 Variable * offset = variable_temporary( _environment, VT_BYTE, "(offset inside temporary storage)");
168
169 Variable * enter = variable_temporary( _environment, VT_CHAR, "(enter)" );
170 Variable * comma = variable_temporary( _environment, VT_CHAR, "(comma)" );
171 Variable * space = variable_temporary( _environment, VT_CHAR, "(space)" );
172 Variable * underscore = variable_temporary( _environment, VT_CHAR, "(underscore)" );
173 Variable * backspace = variable_temporary( _environment, VT_CHAR, "(backspace)" );
174 Variable * size = variable_temporary( _environment, VT_BYTE, "(size max)" );
175 Variable * pressed = variable_temporary( _environment, VT_BYTE, "(key pressed?)");
176 Variable * key = variable_temporary( _environment, VT_CHAR, "(key pressed)");
177 Variable * zero = variable_temporary( _environment, VT_BYTE, "(zero)" );
178
179 cpu_store_8bit( _environment, enter->realName, 13 );
180 cpu_store_8bit( _environment, offset->realName, 0 );
181 cpu_store_8bit( _environment, backspace->realName, 8 );
182 cpu_store_8bit( _environment, space->realName, 32 );
183 cpu_store_8bit( _environment, zero->realName, 0 );
184
185 if ( _environment->lineInput ) {
186 cpu_store_8bit( _environment, comma->realName, 13 );
187 } else {
188 cpu_store_8bit( _environment, comma->realName, _environment->keyboardConfig.separator == 0 ? INPUT_DEFAULT_SEPARATOR : _environment->keyboardConfig.separator );
189 }
190
191 cpu_store_8bit( _environment, size->realName, _environment->keyboardConfig.size == 0 ? INPUT_DEFAULT_SIZE : _environment->keyboardConfig.size );
192 cpu_store_8bit( _environment, underscore->realName, _environment->keyboardConfig.cursor == 0 ? INPUT_DEFAULT_CURSOR : _environment->keyboardConfig.cursor );
193
194 Variable * address = variable_temporary( _environment, VT_ADDRESS, "(address of DSTRING)");
195 cpu_dsfree( _environment, temporary->realName );
196 cpu_dsalloc( _environment, size->realName, temporary->realName );
197 cpu_dsdescriptor( _environment, temporary->realName, address->realName, pressed->realName );
198
199 cpu_label( _environment, repeatLabel );
200
201 print( _environment, underscore->name, 0, _environment->printRaw );
202 cmove_direct( _environment, -1, 0 );
203
204 cia_inkey( _environment, key->realName );
205
206 cpu_bveq( _environment, key->realName, repeatLabel );
207
208 cpu_compare_8bit( _environment, key->realName, backspace->realName, pressed->realName, 1 );
209
210 cpu_bvneq( _environment, pressed->realName, backspaceLabel );
211
212 cpu_compare_8bit( _environment, key->realName, comma->realName, pressed->realName, 1 );
213
214 cpu_bvneq( _environment, pressed->realName, finishedLabel );
215
216 cpu_compare_8bit( _environment, key->realName, enter->realName, pressed->realName, 1 );
217
218 cpu_bvneq( _environment, pressed->realName, finishedLabel );
219
220 print( _environment, key->name, 0, _environment->printRaw );
221
222 cpu_move_8bit_indirect_with_offset2( _environment, key->realName, address->realName, offset->realName );
223
224 cpu_inc( _environment, offset->realName );
225
226 cpu_compare_8bit( _environment, offset->realName, size->realName, pressed->realName, 1 );
227
228 cpu_bveq( _environment, pressed->realName, repeatLabel );
229
230 cpu_jump( _environment, finishedLabel );
231
232 cpu_label( _environment, backspaceLabel );
233
234 cpu_compare_8bit( _environment, offset->realName, zero->realName, pressed->realName, 1 );
235
236 cpu_bvneq( _environment, pressed->realName, repeatLabel );
237
238 cpu_dec( _environment, offset->realName );
239
240 print( _environment, space->name, 0, _environment->printRaw );
241
242 cmove_direct( _environment, -2, 0 );
243
244 print( _environment, space->name, 0, _environment->printRaw );
245
246 cmove_direct( _environment, -1, 0 );
247
248 cpu_jump( _environment, repeatLabel );
249
250 cpu_label( _environment, finishedLabel );
251
252 print( _environment, space->name, 0, _environment->printRaw );
253 cmove_direct( _environment, -1, 0 );
254
255 cpu_compare_8bit( _environment, comma->realName, enter->realName, pressed->realName, 1 );
256 cpu_bveq( _environment, pressed->realName, doneLabel );
257
258 print_newline( _environment );
259
260 cpu_label( _environment, doneLabel );
261
262 cpu_dsresize( _environment, temporary->realName, offset->realName );
263
264 switch( VT_BITWIDTH( result->type ) ) {
265 case 8:
266 case 16:
267 case 32:
268 variable_move( _environment, variable_string_val( _environment, temporary->name )->name, result->name );
269 break;
270 case 0:
271 switch( result->type ) {
272 case VT_DSTRING:
273 variable_move_naked( _environment, temporary->name, result->name );
274 break;
275 default:
276 CRITICAL_INPUT_UNSUPPORTED( _variable, DATATYPE_AS_STRING[result->type] );
277 }
278 }
279
280}
281
282#endif
void cpu_dsfree(Environment *_environment, char *_index)
Definition 6309.c:5917
void cpu_bveq(Environment *_environment, char *_value, char *_label)
Definition 6309.c:334
void cpu_dsresize(Environment *_environment, char *_index, char *_resize)
Definition 6309.c:5937
void cpu_compare_8bit(Environment *_environment, char *_source, char *_destination, char *_other, int _positive)
CPU 6309: emit code to compare two 8 bit values
Definition 6309.c:811
void cpu_inc(Environment *_environment, char *_variable)
Definition 6309.c:4555
void cpu_move_8bit_indirect_with_offset2(Environment *_environment, char *_source, char *_value, char *_offset)
Definition 6309.c:5262
void cpu_label(Environment *_environment, char *_label)
Definition 6309.c:356
void cpu_dec(Environment *_environment, char *_variable)
Definition 6309.c:4630
void cpu_dsalloc(Environment *_environment, char *_size, char *_index)
Definition 6309.c:5895
void cpu_store_8bit(Environment *_environment, char *_destination, int _value)
CPU 6309: emit code to store 8 bit
Definition 6309.c:761
void cpu_jump(Environment *_environment, char *_label)
Definition 6309.c:3739
void cpu_bvneq(Environment *_environment, char *_value, char *_label)
Definition 6309.c:345
void cpu_dsdescriptor(Environment *_environment, char *_index, char *_address, char *_size)
Definition 6309.c:5977
Variable * variable_retrieve(Environment *_environment, char *_name)
int variable_exists(Environment *_environment, char *_name)
Variable * variable_string_val(Environment *_environment, char *_value)
Emit code for = VAL( ... ).
Variable * variable_move(Environment *_environment, char *_source, char *_destination)
Store the value of a variable inside another variable by converting it.
Variable * variable_move_naked(Environment *_environment, char *_source, char *_destination)
Store the value of a variable inside another variable without conversion.
Variable * variable_define(Environment *_environment, char *_name, VariableType _type, int _value)
Define a variable for the program.
Variable * variable_temporary(Environment *_environment, VariableType _type, char *_meaning)
Define a temporary variable.
int size
Definition _optimizer.c:678
int offset
Definition _optimizer.c:681
void input(Environment *_environment, char *_variable, VariableType _default_type)
Definition input.c:43
#define INPUT_DEFAULT_SEPARATOR
Definition atari.h:133
#define INPUT_DEFAULT_SIZE
Definition atari.h:134
#define INPUT_DEFAULT_CURSOR
Definition atari.h:135
void cia_inkey(Environment *_environment, char *_key)
Definition cia.c:115
void cmove_direct(Environment *_environment, int _dx, int _dy)
Definition cmove.c:41
void print_newline(Environment *_environment)
Emit code for print a single newline.
Definition print.c:422
void print(Environment *_environment, char *_value, int _new_line, int _raw)
Emit code for PRINT... instruction.
Definition print.c:141
int lineInput
Definition ugbc.h:3118
KeyboardConfig keyboardConfig
Definition ugbc.h:2435
int printRaw
Definition ugbc.h:3274
char separator
Definition ugbc.h:1982
char * name
Definition ugbc.h:979
char * realName
Definition ugbc.h:982
#define MAX_TEMPORARY_STORAGE
Definition ugbc.h:563
struct _Variable Variable
Structure of a single variable.
#define CRITICAL_INPUT_UNSUPPORTED(v, t)
Definition ugbc.h:3490
struct _Environment Environment
Structure of compilation environment.
@ VT_BYTE
Definition ugbc.h:450
@ VT_CHAR
Definition ugbc.h:498
@ VT_ADDRESS
Definition ugbc.h:465
@ VT_DSTRING
Definition ugbc.h:483
enum _VariableType VariableType
Type of variables.
#define VT_BITWIDTH(t)
Definition ugbc.h:595
#define MAKE_LABEL
Definition ugbc.h:3351
char DATATYPE_AS_STRING[][16]