ugBASIC 1.18
An isomorphic BASIC language compiler for retrocomputers
Loading...
Searching...
No Matches
on_proc.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...PROC
52
53@english
54This command is used to force a call to subroutine 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 call will be performed.
61
62Important: if the ''OPTION CALL AS GOTO'' pragma is in effect, the instruction
63will be considered as a ''GOTO'' rather than a ''GOSUB''. So, no return value and
64no return, at all. This not applies to system calls.
65
66@italian
67Questo comando viene utilizzato per forzare una chiamata a subroutine,
68calcolata da un'espressione. La scelta è tra le posizioni
69elencate, e dipende dal valore dell'espressione al momento in cui viene
70calcolata.
71
72Per funzionare correttamente, l'espressione deve avere un valore compreso
73tra 1 e il numero di destinazioni. Se l'espressione ha un valore di 0 o
74maggiore della destinazione più alta possibile, non sarà eseguito alcun salto.
75
76Importante: se il pragma ''OPTION CALL AS GOTO'' è attivo, l'istruzione
77sarà considerata un ''GOTO'' piuttosto che un ''GOSUB''. Quindi, nessun
78valore di ritorno e, anzi, nessun ritorno sarà previsto. Questo non si applica
79alle chiamate di sistema.
80
81@syntax ON expression PROC name1[, name2 [, ... ] ]
82
83@example ON level PROC level1, level2, level3
84@usedInExample procedures_jumping_01.bas
85
86@target all
87</usermanual> */
88void on_proc( Environment * _environment, char * _expression ) {
89
91
92 Variable * expression = variable_retrieve( _environment, _expression );
93
94 char newLabel[MAX_TEMPORARY_STORAGE]; sprintf(newLabel, "proc%d", UNIQUE_ID );
95
96 Conditional * conditional = malloc( sizeof( Conditional ) );
97 conditional->label = strdup( newLabel );
98 conditional->type = CT_ON_PROC;
99 conditional->expression = variable_cast( _environment, expression->name, expression->type );
100 conditional->expression->locked = 1;
101 conditional->index = 1;
102 conditional->next = _environment->conditionals;
103 _environment->conditionals = conditional;
104
105}
106
116void on_proc_index( Environment * _environment, char * _label ) {
117
118 Conditional * conditional = _environment->conditionals;
119
120 if ( ! conditional ) {
121 CRITICAL_INTERNAL_ERROR("on_proc_index called out of order (1)");
122 }
123
124 if ( conditional->type != CT_ON_PROC ) {
125 CRITICAL_INTERNAL_ERROR("on_proc_index called out of order (1)");
126 }
127
128 if ( !procedure_exists( _environment, _label ) ) {
130 }
131
132 Variable * index = variable_resident( _environment, VT_BYTE, "(index)");
133
134 variable_store( _environment, index->name, conditional->index );
135
136 Variable * expression = variable_retrieve( _environment, conditional->expression->name );
137
138 char newLabel[MAX_TEMPORARY_STORAGE]; sprintf(newLabel, "%s%d", conditional->label, (conditional->index+1) );
139
140 cpu_bveq( _environment, variable_compare( _environment, expression->name, index->name )->realName, newLabel );
141
142 call_procedure( _environment, _label );
143
144 char newLabel2[MAX_TEMPORARY_STORAGE]; sprintf(newLabel2, "%sfinal", conditional->label );
145
146 cpu_jump( _environment, newLabel2 );
147
148 cpu_label( _environment, newLabel );
149
150 ++conditional->index;
151
152};
153
162void on_proc_end( Environment * _environment ) {
163
164 Conditional * conditional = _environment->conditionals;
165
166 if ( ! conditional ) {
167 CRITICAL_INTERNAL_ERROR("on_proc_end called out of order (1)");
168 }
169
170 if ( conditional->type != CT_ON_PROC ) {
171 CRITICAL_INTERNAL_ERROR("on_proc_end called out of order (1)");
172 }
173
174 char newLabel2[MAX_TEMPORARY_STORAGE]; sprintf(newLabel2, "%sfinal", conditional->label );
175
176 cpu_label( _environment, newLabel2 );
177
178 _environment->conditionals->expression->locked = 0;
179
180 _environment->conditionals = _environment->conditionals->next;
181
182};
void cpu_bveq(Environment *_environment, char *_value, char *_label)
Definition 6309.c:334
void cpu_label(Environment *_environment, char *_label)
Definition 6309.c:356
void cpu_jump(Environment *_environment, char *_label)
Definition 6309.c:3739
int procedure_exists(Environment *_environment, char *_name)
Variable * variable_retrieve(Environment *_environment, char *_name)
Variable * variable_resident(Environment *_environment, VariableType _type, char *_meaning)
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 call_procedure(Environment *_environment, char *_name)
Emit code for CALL/PROC ....
Definition call.c:139
void on_proc_index(Environment *_environment, char *_label)
Emit ASM code for ... (of ON ... PROC ...).
Definition on_proc.c:116
void on_proc_end(Environment *_environment)
Emit ASM code for ... (of ON ... PROC ...).
Definition on_proc.c:162
void on_proc(Environment *_environment, char *_expression)
Emit ASM code for ON ... PROC ....
Definition on_proc.c:88
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
int locked
Definition ugbc.h:1009
char * name
Definition ugbc.h:979
char * realName
Definition ugbc.h:982
void * malloc(YYSIZE_T)
#define MAX_TEMPORARY_STORAGE
Definition ugbc.h:563
@ CT_ON_PROC
Definition ugbc.h:1345
#define UNIQUE_ID
Definition ugbc.h:3349
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
#define CRITICAL_ON_CALL_WITH_NOT_EXISTENT_PROCEDURE(s)
Definition ugbc.h:3790
struct _Conditional Conditional
Structure of a single conditional jump.
#define MAKE_LABEL
Definition ugbc.h:3351