ugBASIC 1.18
An isomorphic BASIC language compiler for retrocomputers
Loading...
Searching...
No Matches
abs.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
41extern char DATATYPE_AS_STRING[][16];
42
50/* <usermanual>
51@keyword ABS
52
53@english
54
55The ''ABS'' command is a mathematical function that returns the absolute value
56of a number. In essence, it removes the negative sign from a number, always
57returning a positive or zero value. The parameter ''expression'' is the value whose
58absolute value you want to calculate. This can be a constant numeric value,
59a variable, or a mathematical expression.
60
61The ''ABS'' command is very useful in several situations. When calculating
62the distance between two points, the absolute value ensures that the distance
63is always positive, regardless of the order in which you consider the points.
64You can use ''ABS'' inside conditions to test whether a value is greater
65than or less than a certain threshold, ignoring the sign. In many applications,
66you need to work with absolute values to avoid errors or unexpected results.
67
68The ''ABS'' command can be applied only to integers.
69
70@italian
71Il comando ''ABS'' è una funzione matematica che restituisce il valore assoluto
72di un numero. In sostanza, rimuove il segno negativo da un numero, restituendo
73sempre un valore positivo o zero. Il parametro ''expression'' è il valore di cui
74si desidera calcolare il valore assoluto. Può essere un valore numerico costante,
75una variabile o un'espressione matematica.
76
77Il comando ''ABS'' è molto utile in diverse situazioni. Quando si calcola la
78distanza tra due punti, il valore assoluto assicura che la distanza sia
79sempre positiva, indipendentemente dall'ordine in cui si considerano i punti.
80È possibile utilizzare ''ABS'' all'interno delle condizioni per verificare se
81un valore è maggiore o minore di una certa soglia, ignorando il segno.
82In molte applicazioni, è necessario lavorare con valori assoluti per evitare
83errori o risultati imprevisti.
84
85Il comando ''ABS'' può essere usato solo con valori interi.
86
87@syntax = ABS(expression)
88
89@example ' Calculate the distance between two abscissa
90@example distance = ABS(x1 - x2)
91
92@usedInExample maths_abs_01.bas
93@usedInExample contrib_if_test_speed.bas
94
95@target all
96</usermanual> */
97Variable * absolute( Environment * _environment, char * _value ) {
98 Variable * value = variable_retrieve( _environment, _value );
99
100 Variable * result = variable_temporary( _environment, VT_UNSIGN( value->type ), "(result of ABS)");
101
103
104 char positiveLabel[MAX_TEMPORARY_STORAGE]; sprintf(positiveLabel, "%spos", label );
105 char negativeLabel[MAX_TEMPORARY_STORAGE]; sprintf(negativeLabel, "%snev", label );
106 char endLabel[MAX_TEMPORARY_STORAGE]; sprintf(endLabel, "%send", label );
107
108 switch( VT_BITWIDTH( value->type ) ) {
109 case 32:
110 if ( VT_SIGNED( value->type ) ) {
111
112 #if CPU_BIG_ENDIAN
113 cpu_less_than_and_branch_8bit_const( _environment, value->realName, 0x80, positiveLabel, 0, 0 );
114 #else
115 cpu_less_than_and_branch_8bit_const( _environment, address_displacement( _environment, value->realName, "3" ), 0x80, positiveLabel, 0, 0 );
116 #endif
117
118 cpu_label( _environment, negativeLabel );
119 cpu_complement2_32bit( _environment, value->realName, result->realName );
120 cpu_jump( _environment, endLabel );
121
122 cpu_label( _environment, positiveLabel );
123 variable_move( _environment, value->name, result->name );
124 cpu_label( _environment, endLabel );
125
126 } else {
127 variable_move( _environment, value->name, result->name );
128 }
129 break;
130 case 16:
131 if ( VT_SIGNED( value->type ) ) {
132 Variable * compareResult = variable_temporary( _environment, VT_SBYTE, "(result of ABS)");
133
134 #if CPU_BIG_ENDIAN
135 cpu_less_than_and_branch_8bit_const( _environment, value->realName, 0x80, positiveLabel, 0, 0 );
136 #else
137 cpu_less_than_and_branch_8bit_const( _environment, address_displacement( _environment, value->realName, "1" ), 0x80, positiveLabel, 0, 0 );
138 #endif
139
140 cpu_label( _environment, negativeLabel );
141 cpu_complement2_16bit( _environment, value->realName, result->realName );
142 cpu_jump( _environment, endLabel );
143
144 cpu_label( _environment, positiveLabel );
145 variable_move( _environment, value->name, result->name );
146 cpu_label( _environment, endLabel );
147
148 } else {
149 variable_move( _environment, value->name, result->name );
150 }
151 break;
152 case 8:
153 if ( VT_SIGNED( value->type ) ) {
154 Variable * compareResult = variable_temporary( _environment, VT_SBYTE, "(result of ABS)");
155
156 cpu_less_than_and_branch_8bit_const( _environment, value->realName, 0x80, positiveLabel, 0, 0 );
157
158 cpu_label( _environment, negativeLabel );
159 cpu_complement2_8bit( _environment, value->realName, result->realName );
160 cpu_jump( _environment, endLabel );
161
162 cpu_label( _environment, positiveLabel );
163 variable_move( _environment, value->name, result->name );
164 cpu_label( _environment, endLabel );
165
166 } else {
167 variable_move( _environment, value->name, result->name );
168 }
169 break;
170 case 0:
172 break;
173 }
174
175 return result;
176}
177
void cpu_less_than_and_branch_8bit_const(Environment *_environment, char *_source, int _destination, char *_other, int _equal, int _signed)
Definition 6309.c:970
void cpu_complement2_8bit(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:6045
void cpu_label(Environment *_environment, char *_label)
Definition 6309.c:356
void cpu_complement2_16bit(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:6057
void cpu_complement2_32bit(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:6070
void cpu_jump(Environment *_environment, char *_label)
Definition 6309.c:3739
Variable * variable_retrieve(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_temporary(Environment *_environment, VariableType _type, char *_meaning)
Define a temporary variable.
char * address_displacement(Environment *_environment, char *_address, char *_displacement)
Variable * absolute(Environment *_environment, char *_value)
Return the absolute value of a variable.
Definition abs.c:97
char * name
Definition ugbc.h:979
VariableType type
Definition ugbc.h:988
char * realName
Definition ugbc.h:982
#define MAX_TEMPORARY_STORAGE
Definition ugbc.h:563
#define VT_SIGNED(t)
Definition ugbc.h:618
#define VT_UNSIGN(t)
Definition ugbc.h:621
struct _Variable Variable
Structure of a single variable.
struct _Environment Environment
Structure of compilation environment.
@ VT_SBYTE
Definition ugbc.h:452
#define VT_BITWIDTH(t)
Definition ugbc.h:595
#define CRITICAL_ABS_UNSUPPORTED(v, t)
Definition ugbc.h:3477
#define MAKE_LABEL
Definition ugbc.h:3351
char DATATYPE_AS_STRING[][16]