ugBASIC 1.18
An isomorphic BASIC language compiler for retrocomputers
Loading...
Searching...
No Matches
end_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
47/* <usermanual>
48@keyword PROCEDURE...END PROC
49
50@english
51As an option, you can specify a value for the function to return.
52The value must be indicated in square brackets (''[...]'').
53The value will then be copied into the ''PARAM'' variable and
54returned by the call, if the call was made in the context of an expression.
55
56Important: if the ''OPTION CALL AS GOTO'' pragma is in effect, the instruction
57will be considered as a ''NOP''.
58
59@italian
60Come opzione è possibile indicare un valore da restituire da parte
61della procedura. Il valore va indicato tra parentesi quadre.
62Il valore sarà, quindi, copiato nella variable ''PARAM'' e restituito
63dalla chiamata, se la chiamata è stata fatta nel contesto di una espressione.
64
65Importante: se il pragma ''OPTION CALL AS GOTO'' è attivo, l'istruzione
66sarà considerata un ''NOP''.
67
68@example PROCEDURE hundred
69@example END PROC[100]
70
71</usermanual> */
72void end_procedure( Environment * _environment, char * _value ) {
73
74 if ( _environment->emptyProcedure ) {
75 return;
76 }
77
78 if ( ! _environment->procedureName ) {
80 }
81
82 if ( _value ) {
83 char paramName[MAX_TEMPORARY_STORAGE]; sprintf(paramName,"%s__PARAM", _environment->procedureName );
84 Variable * value;
85 if ( variable_exists( _environment, _value ) ) {
86 value = variable_retrieve( _environment, _value );
87 } else {
88 value = variable_retrieve_or_define( _environment, _value, _environment->defaultVariableType, 0 );
89 }
90 Variable * param = variable_define( _environment, paramName, value->type, 0 );
91 variable_move( _environment, value->name, param->name );
92 }
93
94 char procedureAfterLabel[MAX_TEMPORARY_STORAGE]; sprintf(procedureAfterLabel, "%safter", _environment->procedureName );
95
96 if ( _environment->protothread ) {
97 cpu_protothread_set_state( _environment, "PROTOTHREADCT", PROTOTHREAD_STATUS_ENDED );
98 }
99
100 if ( ! _environment->optionCallAsGoto ) {
101 cpu_return( _environment );
102 }
103
104 if ( _environment->protothread ) {
105
106 char procedureParallelDispatch[MAX_TEMPORARY_STORAGE]; sprintf(procedureParallelDispatch, "%sdispatch", _environment->procedureName );
107 char procedureEndedLabel[MAX_TEMPORARY_STORAGE]; sprintf(procedureEndedLabel, "%sended", _environment->procedureName );
108 char procedureSuspendedLabel[MAX_TEMPORARY_STORAGE]; sprintf(procedureSuspendedLabel, "%ssusp", _environment->procedureName );
109 char protothreadLabelWaiting[MAX_TEMPORARY_STORAGE]; sprintf(protothreadLabelWaiting, "%spt%d", _environment->procedureName, 0 );
110
111 cpu_label( _environment, procedureParallelDispatch );
112
113 Variable * status = variable_temporary( _environment, VT_BYTE, "(status)" );
114
115 cpu_protothread_get_state( _environment, "PROTOTHREADCT", status->realName );
116
117 cpu_compare_and_branch_8bit_const( _environment, status->realName, PROTOTHREAD_STATUS_ENDED, procedureEndedLabel, 1 );
118
119 cpu_compare_and_branch_8bit_const( _environment, status->realName, PROTOTHREAD_STATUS_PAUSED, procedureSuspendedLabel, 1 );
120 // cpu_compare_and_branch_8bit_const( _environment, status->realName, PROTOTHREAD_STATUS_WAITING, protothreadLabelWaiting, 1 );
121
122 if ( _environment->protothreadStep > 1 ) {
123 outline0("; start end proc with parallel");
124 Variable * step = variable_temporary( _environment, VT_BYTE, "(dispatch)");
125 cpu_protothread_restore( _environment, "PROTOTHREADCT", step->realName );
126
127 int i = 0;
128
130 for(i=0;i<_environment->protothreadStep; ++i) {
131 outline1("; step %d", i );
132 char protothreadLabel[MAX_TEMPORARY_STORAGE]; sprintf(protothreadLabel, "%spt%d", _environment->procedureName, i );
133 cpu_execute_compare_and_branch_8bit_const( _environment, i, protothreadLabel, 1 );
134 }
135 cpu_protothread_save( _environment, "PROTOTHREADCT", 1 );
136 char protothreadLabel[MAX_TEMPORARY_STORAGE]; sprintf(protothreadLabel, "%spt%d", _environment->procedureName, 0 );
137 cpu_jump( _environment, protothreadLabel );
138 }
139
140 cpu_label( _environment, procedureEndedLabel );
141 cpu_label( _environment, procedureSuspendedLabel );
142 cpu_return( _environment );
143
144 }
145
146
147 cpu_label( _environment, procedureAfterLabel );
148
149 Variable * current = _environment->procedureVariables;
150
151 if ( current ) {
152 while( current->next ) {
153 current->name = current->realName;
154 current = current->next;
155 }
156 current->name = current->realName;
157 }
158
159 current = _environment->procedureVariables;
160
161 Variable * varLast = _environment->variables;
162 if ( varLast ) {
163 while( varLast->next ) {
164 varLast = varLast->next;
165 }
166 varLast->next = current;
167 } else {
168 _environment->variables = current;
169 }
170
171 _environment->procedureName = NULL;
172
173 _environment->procedureVariables = NULL;
174
175};
176
void cpu_protothread_get_state(Environment *_environment, char *_index, char *_state)
Definition 6309.c:6237
void cpu_protothread_restore(Environment *_environment, char *_index, char *_step)
Definition 6309.c:6214
void cpu_protothread_save(Environment *_environment, char *_index, int _step)
Definition 6309.c:6203
void cpu_protothread_set_state(Environment *_environment, char *_index, int _state)
Definition 6309.c:6226
void cpu_label(Environment *_environment, char *_label)
Definition 6309.c:356
void cpu_jump(Environment *_environment, char *_label)
Definition 6309.c:3739
void cpu_prepare_for_compare_and_branch_8bit(Environment *_environment, char *_source)
Definition 6309.c:841
void cpu_return(Environment *_environment)
Definition 6309.c:4030
void cpu_execute_compare_and_branch_8bit_const(Environment *_environment, int _destination, char *_label, int _positive)
CPU 6309: emit code to compare two 8 bit values and jump if they are equal/different
Definition 6309.c:901
void cpu_compare_and_branch_8bit_const(Environment *_environment, char *_source, int _destination, char *_label, int _positive)
CPU 6309: emit code to compare two 8 bit values and jump if they are equal/different
Definition 6309.c:876
Variable * variable_retrieve(Environment *_environment, char *_name)
Variable * variable_retrieve_or_define(Environment *_environment, char *_name, VariableType _type, int _value)
int variable_exists(Environment *_environment, char *_name)
Variable * variable_move(Environment *_environment, char *_source, char *_destination)
Store the value of a variable inside another variable by converting it.
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.
void end_procedure(Environment *_environment, char *_value)
Emit code for END PROC.
Definition end_proc.c:72
Variable * procedureVariables
Definition ugbc.h:2626
int protothread
Definition ugbc.h:2830
VariableType defaultVariableType
Definition ugbc.h:2956
int optionCallAsGoto
Definition ugbc.h:2961
int protothreadStep
Definition ugbc.h:2840
Variable * variables
Definition ugbc.h:2616
char * procedureName
Definition ugbc.h:2775
int emptyProcedure
Definition ugbc.h:2932
struct _Variable * next
Definition ugbc.h:1225
char * name
Definition ugbc.h:979
VariableType type
Definition ugbc.h:988
char * realName
Definition ugbc.h:982
#define PROTOTHREAD_STATUS_ENDED
Definition ugbc.h:4550
#define MAX_TEMPORARY_STORAGE
Definition ugbc.h:563
struct _Variable Variable
Structure of a single variable.
#define CRITICAL_PROCEDURE_NOT_OPENED()
Definition ugbc.h:3482
struct _Environment Environment
Structure of compilation environment.
@ VT_BYTE
Definition ugbc.h:450
#define PROTOTHREAD_STATUS_PAUSED
Definition ugbc.h:4551
#define outline0(s)
Definition ugbc.h:4252
#define outline1(s, a)
Definition ugbc.h:4253