mes/module/mes/libc.mes

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
))