genie-misc.c
1 //! @file genie-misc.c
2 //! @author J. Marcel van der Veer
3
4 //! @section Copyright
5 //!
6 //! This file is part of Algol68G - an Algol 68 compiler-interpreter.
7 //! Copyright 2001-2024 J. Marcel van der Veer [algol68g@xs4all.nl].
8
9 //! @section License
10 //!
11 //! This program is free software; you can redistribute it and/or modify it
12 //! under the terms of the GNU General Public License as published by the
13 //! Free Software Foundation; either version 3 of the License, or
14 //! (at your option) any later version.
15 //!
16 //! This program is distributed in the hope that it will be useful, but
17 //! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18 //! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 //! more details. You should have received a copy of the GNU General Public
20 //! License along with this program. If not, see [http://www.gnu.org/licenses/].
21
22 //! @section Synopsis
23 //!
24 //! Miscellaneous interpreter routines.
25
26 #include "a68g.h"
27 #include "a68g-genie.h"
28 #include "a68g-prelude.h"
29
30 #define VECTOR_SIZE 512
31 #define FD_READ 0
32 #define FD_WRITE 1
33
34 //! @brief Nop for the genie, for instance '+' for INT or REAL.
35
36 void genie_idle (NODE_T * p)
37 {
38 (void) p;
39 }
40
41 //! @brief Unimplemented feature handler.
42
43 void genie_unimplemented (NODE_T * p)
44 {
45 diagnostic (A68_RUNTIME_ERROR, p, ERROR_UNIMPLEMENTED);
46 exit_genie (p, A68_RUNTIME_ERROR);
47 }
48
49 //! @brief PROC sleep = (INT) INT
50
51 void genie_sleep (NODE_T * p)
52 {
53 A68_INT secs;
54 POP_OBJECT (p, &secs, A68_INT);
55 int wait = VALUE (&secs);
56 PRELUDE_ERROR (wait < 0, p, ERROR_INVALID_ARGUMENT, M_INT);
57 while (wait > 0) {
58 wait = (int) sleep ((unt) wait);
59 }
60 PUSH_VALUE (p, (INT_T) 0, A68_INT);
61 }
62
63 //! @brief PROC system = (STRING) INT
64
65 void genie_system (NODE_T * p)
66 {
67 A68_REF cmd;
68 POP_REF (p, &cmd);
69 CHECK_INIT (p, INITIALISED (&cmd), M_STRING);
70 int size = 1 + a68_string_size (p, cmd);
71 A68_REF ref_z = heap_generator (p, M_C_STRING, 1 + size);
72 PUSH_VALUE (p, system (a_to_c_string (p, DEREF (char, &ref_z), cmd)), A68_INT);
73 }
74
75 //! @brief PROC (PROC VOID) VOID on gc event
76
77 void genie_on_gc_event (NODE_T * p)
78 {
79 POP_PROCEDURE (p, &A68 (on_gc_event));
80 }
81
82 //! @brief Generic procedure for OP AND BECOMES (+:=, -:=, ...).
83
84 void genie_f_and_becomes (NODE_T * p, MOID_T * ref, GPROC * f)
85 {
86 MOID_T *mode = SUB (ref);
87 int size = SIZE (mode);
88 BYTE_T *src = STACK_OFFSET (-size), *addr;
89 A68_REF *dst = (A68_REF *) STACK_OFFSET (-size - A68_REF_SIZE);
90 CHECK_REF (p, *dst, ref);
91 addr = ADDRESS (dst);
92 PUSH (p, addr, size);
93 genie_check_initialisation (p, STACK_OFFSET (-size), mode);
94 PUSH (p, src, size);
95 (*f) (p);
96 POP (p, addr, size);
97 DECREMENT_STACK_POINTER (p, size);
98 }
99
100 //! @brief INT system heap pointer
101
102 void genie_system_heap_pointer (NODE_T * p)
103 {
104 PUSH_VALUE (p, (int) (A68_HP), A68_INT);
105 }
106
107 //! @brief INT system stack pointer
108
109 void genie_system_stack_pointer (NODE_T * p)
110 {
111 BYTE_T stack_offset;
112 PUSH_VALUE (p, (int) (A68 (system_stack_offset) - &stack_offset), A68_INT);
113 }
© 2002-2024 J.M. van der Veer (jmvdveer@xs4all.nl)
|