326 lines
5.3 KiB
Scheme
326 lines
5.3 KiB
Scheme
;;; -*-scheme-*-
|
|
|
|
;;; Mes --- Maxwell Equations of Software
|
|
;;; Copyright © 2016,2017 Jan Nieuwenhuizen <janneke@gnu.org>
|
|
;;;
|
|
;;; This file is part of Mes.
|
|
;;;
|
|
;;; Mes is free software; you can redistribute it and/or modify it
|
|
;;; under the terms of the GNU General Public License as published by
|
|
;;; the Free Software Foundation; either version 3 of the License, or (at
|
|
;;; your option) any later version.
|
|
;;;
|
|
;;; Mes is distributed in the hope that it will be useful, but
|
|
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
;;; GNU General Public License for more details.
|
|
;;;
|
|
;;; You should have received a copy of the GNU General Public License
|
|
;;; along with Mes. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
;;; Commentary:
|
|
|
|
;;; libc.mes provides a minimal portable C library for mescc.
|
|
|
|
;;; Code:
|
|
|
|
(cond-expand
|
|
(guile-2)
|
|
(guile)
|
|
(mes
|
|
(mes-use-module (nyacc lang c99 parser))
|
|
(mes-use-module (mes libc-i386))))
|
|
|
|
(define _start
|
|
(let* ((argc-argv (i386:_start))
|
|
(ast (with-input-from-string
|
|
(string-append "int _start () {int i;asm(\"" argc-argv "\");i=main ();exit (i);}")
|
|
parse-c99)))
|
|
ast))
|
|
|
|
(define strlen
|
|
(let* ((ast (with-input-from-string
|
|
"
|
|
int
|
|
strlen (char const* s)
|
|
{
|
|
int i = 0;
|
|
while (s[i]) i++;
|
|
return i;
|
|
}
|
|
"
|
|
;;paredit:"
|
|
parse-c99)))
|
|
ast))
|
|
|
|
(define getchar
|
|
(let* ((ast (with-input-from-string
|
|
"
|
|
int g_stdin = 0;
|
|
int ungetc_char = -1;
|
|
char ungetc_buf[2];
|
|
int
|
|
getchar ()
|
|
{
|
|
char c;
|
|
int i;
|
|
if (ungetc_char == -1)
|
|
{
|
|
int r = read (g_stdin, &c, 1);
|
|
if (r < 1) return -1;
|
|
i = c;
|
|
}
|
|
else
|
|
{
|
|
//FIXME
|
|
//i = ungetc_buf[ungetc_char--];
|
|
i = ungetc_buf[ungetc_char];
|
|
//ungetc_char--;
|
|
ungetc_char = ungetc_char - 1;
|
|
}
|
|
if (i < 0) i += 256;
|
|
|
|
return i;
|
|
}
|
|
"
|
|
;;paredit:"
|
|
parse-c99)))
|
|
ast))
|
|
|
|
(define assert_fail
|
|
(let* ((ast (with-input-from-string
|
|
"
|
|
void
|
|
assert_fail (char* s)
|
|
{
|
|
eputs (\"assert fail: \");
|
|
eputs (s);
|
|
eputs (\"\n\");
|
|
//*((int*)0) = 0;
|
|
char *fail = s;
|
|
fail = 0;
|
|
*fail = 0;
|
|
}
|
|
"
|
|
;;paredit:"
|
|
parse-c99)))
|
|
ast))
|
|
|
|
(define ungetc
|
|
(let* ((ast (with-input-from-string
|
|
"
|
|
//#define assert(x) ((x) ? (void)0 : assert_fail (#x))
|
|
int
|
|
ungetc (int c, int fd)
|
|
{
|
|
//FIXME
|
|
//assert (ungetc_char < 2);
|
|
//assert (ungetc_char == -1 || ungetc_char < 2);
|
|
//FIXME
|
|
//ungetc_buf[++ungetc_char] = c;
|
|
ungetc_char++;
|
|
ungetc_buf[ungetc_char] = c;
|
|
return c;
|
|
}
|
|
"
|
|
;;paredit:"
|
|
parse-c99)))
|
|
ast))
|
|
|
|
(define putchar
|
|
(let* ((ast (with-input-from-string
|
|
"
|
|
int
|
|
putchar (int c)
|
|
{
|
|
write (1, (char*)&c, 1);
|
|
return 0;
|
|
}
|
|
"
|
|
;;paredit:"
|
|
parse-c99)))
|
|
ast))
|
|
|
|
(define fputc
|
|
(let* ((ast (with-input-from-string
|
|
"
|
|
int
|
|
fputc (int c, int fd)
|
|
{
|
|
write (fd, (char*)&c, 1);
|
|
return 0;
|
|
}
|
|
"
|
|
;;paredit:"
|
|
parse-c99)))
|
|
ast))
|
|
|
|
(define eputs
|
|
(let* ((ast (with-input-from-string
|
|
"
|
|
int
|
|
eputs (char const* s)
|
|
{
|
|
int i = strlen (s);
|
|
write (2, s, i);
|
|
return 0;
|
|
}
|
|
"
|
|
;;paredit:"
|
|
parse-c99)))
|
|
ast))
|
|
|
|
(define fputs
|
|
(let* ((ast (with-input-from-string
|
|
"
|
|
int
|
|
fputs (char const* s, int fd)
|
|
{
|
|
int i = strlen (s);
|
|
write (fd, s, i);
|
|
return 0;
|
|
}
|
|
"
|
|
;;paredit:"
|
|
parse-c99)))
|
|
ast))
|
|
|
|
(define puts
|
|
(let* ((ast (with-input-from-string
|
|
"
|
|
int
|
|
puts (char const* s)
|
|
{
|
|
int i = strlen (s);
|
|
write (1, s, i);
|
|
return 0;
|
|
}
|
|
"
|
|
;;paredit:"
|
|
parse-c99)))
|
|
ast))
|
|
|
|
(define strcmp
|
|
(let* ((ast (with-input-from-string
|
|
"
|
|
int
|
|
strcmp (char const* a, char const* b)
|
|
{
|
|
while (*a && *b && *a == *b)
|
|
{
|
|
a++;b++;
|
|
}
|
|
return *a - *b;
|
|
}
|
|
"
|
|
;;paredit:"
|
|
parse-c99)))
|
|
ast))
|
|
|
|
(define itoa
|
|
(let* ((ast (with-input-from-string
|
|
"
|
|
char itoa_buf[10];
|
|
|
|
char const*
|
|
itoa (int x)
|
|
{
|
|
//static char itoa_buf[10];
|
|
//char *p = buf+9;
|
|
char *p = itoa_buf;
|
|
p += 9;
|
|
*p-- = 0;
|
|
|
|
//int sign = x < 0;
|
|
int sign;
|
|
sign = x < 0;
|
|
if (sign)
|
|
x = -x;
|
|
|
|
do
|
|
{
|
|
*p-- = '0' + (x % 10);
|
|
x = x / 10;
|
|
} while (x);
|
|
|
|
if (sign)
|
|
*p-- = '-';
|
|
|
|
return p+1;
|
|
}
|
|
"
|
|
;;paredit:"
|
|
parse-c99)))
|
|
ast))
|
|
|
|
(define isdigit
|
|
(let* ((ast (with-input-from-string
|
|
"
|
|
int
|
|
isdigit (char c)
|
|
{
|
|
//return (c>='0') && (c<='9');
|
|
if (c>='0' && c<='9') return 1;
|
|
return 0;
|
|
}
|
|
"
|
|
;;paredit:"
|
|
parse-c99)))
|
|
ast))
|
|
|
|
(define malloc
|
|
(let* ((ast (with-input-from-string
|
|
"
|
|
//void *g_malloc_base = 0;
|
|
char *g_malloc_base = 0;
|
|
|
|
//void *
|
|
int *
|
|
malloc (int size)
|
|
{
|
|
//void *p = brk (0);
|
|
char *p = 0;
|
|
p = brk (0);
|
|
if (!g_malloc_base) g_malloc_base = p;
|
|
brk (p+size);
|
|
return p;
|
|
}
|
|
"
|
|
;;paredit:"
|
|
parse-c99)))
|
|
ast))
|
|
|
|
(define realloc
|
|
(let* ((ast (with-input-from-string
|
|
"
|
|
//void *
|
|
int *
|
|
//realloc (void *p, int size)
|
|
realloc (int *p, int size)
|
|
{
|
|
brk (g_malloc_base + size);
|
|
return g_malloc_base;
|
|
}
|
|
"
|
|
;;paredit:"
|
|
parse-c99)))
|
|
ast))
|
|
|
|
(define libc
|
|
(list
|
|
strlen
|
|
getchar
|
|
assert_fail
|
|
ungetc
|
|
putchar
|
|
fputc
|
|
eputs
|
|
fputs
|
|
puts
|
|
strcmp
|
|
itoa
|
|
isdigit
|
|
malloc
|
|
realloc
|
|
))
|