ugBASIC 1.18
An isomorphic BASIC language compiler for retrocomputers
Loading...
Searching...
No Matches
on_goto.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
50/* <usermanual>
51@keyword ON...GOTO
52
53@english
54This command is used to force a unconditional jump to a pre-defined position when a
55specific expression is calculated. The choice is done against several positions,
56and it depends on what value is held by the expression at the time it is spotted.
57
58To work properly, the expression must have a value from 1 up to the number of
59the highest possible destination. If the expression has a value of 0 or
60greater than the highest possibile destination, no jump will be performed.
61
62@italian
63Questo comando viene utilizzato per forzare un salto incondizionato a una
64posizione predefinita, calcolata da un'espressione. La scelta è tra le posizioni
65elencate, e dipende dal valore dell'espressione al momento in cui viene
66calcolata.
67
68Per funzionare correttamente, l'espressione deve avere un valore compreso
69tra 1 e il numero di destinazioni. Se l'espressione ha un valore di 0 o
70maggiore della destinazione più alta possibile, non sarà eseguito alcun salto.
71
72@syntax ON expression GOTO label1[, label2[, ... ] ]
73
74@example ON level GOTO level1, level2, level3
75@usedInExample control_by_expression_02.bas
76
77@target all
78</usermanual> */
79void on_goto( Environment * _environment, char * _expression ) {
80
82
83 Variable * expression = variable_retrieve( _environment, _expression );
84
85 Conditional * conditional = malloc( sizeof( Conditional ) );
86 conditional->label = strdup( label );
87 conditional->type = CT_ON_GOTO;
88 conditional->expression = variable_cast( _environment, expression->name, expression->type );
89 conditional->expression->locked = 1;
90 conditional->index = 1;
91 conditional->next = _environment->conditionals;
92 _environment->conditionals = conditional;
93
94}
95
105void on_goto_index( Environment * _environment, char * _label ) {
106
107 Conditional * conditional = _environment->conditionals;
108
109 if ( ! conditional ) {
110 CRITICAL_INTERNAL_ERROR("on_goto_index called out of order (1)");
111 }
112
113 if ( conditional->type != CT_ON_GOTO ) {
114 CRITICAL_INTERNAL_ERROR("on_goto_index called out of order (2)");
115 }
116
117 char realLabel[MAX_TEMPORARY_STORAGE];
118 if (strcmp(_label, "q" ) == 0 && _environment->vestigialConfig.rchack_ostra_1172 ) {
119 sprintf( realLabel, "lbl%s", _label );
120 } else {
121 strcpy( realLabel, _label );
122 }
123 label_referred_define_named( _environment, realLabel );
124
125 Variable * index = variable_resident( _environment, VT_BYTE, "(index)");
126
127 variable_store( _environment, index->name, conditional->index );
128
129 Variable * expression = variable_retrieve( _environment, conditional->expression->name );
130
131 cpu_bvneq( _environment, variable_compare( _environment, expression->name, index->name )->realName, realLabel );
132
133 ++conditional->index;
134
135};
136
146void on_goto_number( Environment * _environment, int _number ) {
147
148 label_referred_define_numeric( _environment, _number );
149
150 char label[MAX_TEMPORARY_STORAGE]; sprintf( label, "_linenumber%d", _number );
151
152 on_goto_index( _environment, label );
153
154};
155
164void on_goto_end( Environment * _environment ) {
165
166 Conditional * conditional = _environment->conditionals;
167
168 if ( ! conditional ) {
169 CRITICAL_INTERNAL_ERROR("on_goto_end called out of order (1)");
170 }
171
172 if ( conditional->type != CT_ON_GOTO ) {
173 CRITICAL_INTERNAL_ERROR("on_goto_end called out of order (2)");
174 }
175
176 _environment->conditionals->expression->locked = 0;
177
178 _environment->conditionals = _environment->conditionals->next;
179
180};
void cpu_bvneq(Environment *_environment, char *_value, char *_label)
Definition 6309.c:345
Variable * variable_retrieve(Environment *_environment, char *_name)
void label_referred_define_named(Environment *_environment, char *_label)
Variable * variable_resident(Environment *_environment, VariableType _type, char *_meaning)
void label_referred_define_numeric(Environment *_environment, int _label)
Variable * variable_cast(Environment *_environment, char *_source, VariableType _type)
Cast a variable from a type to another.
Variable * variable_compare(Environment *_environment, char *_source, char *_destination)
Compare two variable and return the result of comparation.
Variable * variable_store(Environment *_environment, char *_destination, unsigned int _value)
Store a direct value to a variable.
void on_goto_end(Environment *_environment)
Emit ASM code for ... (of ON ... GOTO ...).
Definition on_goto.c:164
void on_goto_index(Environment *_environment, char *_label)
Emit ASM code for ... (of ON ... GOTO ...).
Definition on_goto.c:105
void on_goto_number(Environment *_environment, int _number)
Emit ASM code for ... (of ON ... GOTO ...).
Definition on_goto.c:146
void on_goto(Environment *_environment, char *_expression)
Emit ASM code for ON ... GOTO ....
Definition on_goto.c:79
struct _Conditional * next
Definition ugbc.h:1378
int index
Definition ugbc.h:1372
ConditionalType type
Definition ugbc.h:1363
char * label
Definition ugbc.h:1366
Variable * expression
Definition ugbc.h:1369
Conditional * conditionals
Definition ugbc.h:2664
VestigialConfig vestigialConfig
Definition ugbc.h:2442
int locked
Definition ugbc.h:1009
char * name
Definition ugbc.h:979
char * realName
Definition ugbc.h:982
char rchack_ostra_1172
Definition ugbc.h:2020
void * malloc(YYSIZE_T)
#define MAX_TEMPORARY_STORAGE
Definition ugbc.h:563
@ CT_ON_GOTO
Definition ugbc.h:1339
struct _Variable Variable
Structure of a single variable.
#define CRITICAL_INTERNAL_ERROR(v)
Definition ugbc.h:3443
struct _Environment Environment
Structure of compilation environment.
@ VT_BYTE
Definition ugbc.h:450
struct _Conditional Conditional
Structure of a single conditional jump.
#define MAKE_LABEL
Definition ugbc.h:3351