mescc: Refactor mlibc compilation.
* libc/libc-mes.c: New file. Contents from module/mes/libc.mes, module/mes/libc-i386.mes. * libc/libc-gcc.c: Rename from libc/mlibc.c, include libc/mstart.c * libc/mstart.c: Remove. * module/mes/libc-i386.mes: Remove. * module/mes/libc-i386.scm: Remove. * module/mes/libc.mes: Remove. * module/mes/libc.scm: Remove. * GNUmakefile (CFLAGS): Include libc-gcc.c (WAS: mlibc.c). * make/bin-mlibc.make (C_FLAGS): Remove start.c include. * make/mescc-guile.make: Rewrite using compile, link. * make/mescc-mes.make: Likewise. * scaffold/m.c: Update.
This commit is contained in:
parent
2027754a59
commit
3c880bbb56
|
@ -1,11 +1,12 @@
|
|||
SHELL:=bash
|
||||
export SHELL
|
||||
.export: SHELL
|
||||
QUIET:=@
|
||||
|
||||
default: all
|
||||
|
||||
MES_DEBUG:=1
|
||||
CFLAGS:=--std=gnu99 -O0 -g --include mlibc.c
|
||||
CFLAGS:=--std=gnu99 -O0 -g --include libc-gcc.c
|
||||
OUT:=out
|
||||
|
||||
SUBDIRS:=\
|
||||
|
|
|
@ -24,9 +24,11 @@ int g_stdin = 0;
|
|||
#include <stdio.h>
|
||||
#include <mlibc.h>
|
||||
|
||||
#if __GNUC__ && !POSIX
|
||||
|
||||
#if __GNUC__
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#if __GNUC__ && !POSIX
|
||||
|
||||
void
|
||||
exit (int code)
|
||||
|
@ -503,3 +505,39 @@ fdungetc (int c, int fd)
|
|||
}
|
||||
|
||||
#endif // POSIX
|
||||
|
||||
#if __GNUC__ && !POSIX
|
||||
void
|
||||
_start ()
|
||||
{
|
||||
// char **;
|
||||
asm (
|
||||
"mov %%ebp,%%eax\n\t"
|
||||
"addl $4,%%eax\n\t"
|
||||
"movzbl (%%eax),%%eax\n\t"
|
||||
"addl $3,%%eax\n\t"
|
||||
"shl $2,%%eax\n\t"
|
||||
"add %%ebp,%%eax\n\t"
|
||||
"movl %%eax,%0\n\t"
|
||||
: "=g_environment" (g_environment)
|
||||
: //no inputs ""
|
||||
);
|
||||
int r;
|
||||
asm (
|
||||
"mov %%ebp,%%eax\n\t"
|
||||
"addl $8,%%eax\n\t"
|
||||
"push %%eax\n\t"
|
||||
|
||||
"mov %%ebp,%%eax\n\t"
|
||||
"addl $4,%%eax\n\t"
|
||||
"movzbl (%%eax),%%eax\n\t"
|
||||
"push %%eax\n\t"
|
||||
|
||||
"call main\n\t"
|
||||
"movl %%eax,%0\n\t"
|
||||
: "=r" (r)
|
||||
: //no inputs ""
|
||||
);
|
||||
exit (r);
|
||||
}
|
||||
#endif // __GNUC__ && !POSIX
|
387
libc/libc-mes.c
Normal file
387
libc/libc-mes.c
Normal file
|
@ -0,0 +1,387 @@
|
|||
/* -*-comment-start: "//";comment-end:""-*-
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
int g_stdin = 0;
|
||||
|
||||
void
|
||||
exit ()
|
||||
{
|
||||
asm (".byte 0x8b 0x5d 0x08"); // mov 0x8(%ebp),%ebx
|
||||
asm (".byte 0xb8 0x01 0x00 0x00 0x00"); // mov $0x1,%eax
|
||||
asm (".byte 0xcd 0x80"); // int $0x80
|
||||
}
|
||||
|
||||
void
|
||||
read ()
|
||||
{
|
||||
asm (".byte 0x8b 0x5d 0x08"); // mov 0x8(%ebp),%ebx
|
||||
asm (".byte 0x8b 0x4d 0x0c"); // mov 0xc(%ebp),%ecx
|
||||
asm (".byte 0x8b 0x55 0x10"); // mov 0x10(%ebp),%edx
|
||||
|
||||
asm (".byte 0xb8 0x03 0x00 0x00 0x00"); // mov $0x3,%eax
|
||||
asm (".byte 0xcd 0x80"); // int $0x80
|
||||
}
|
||||
|
||||
void
|
||||
write ()
|
||||
{
|
||||
asm (".byte 0x8b 0x5d 0x08"); // mov 0x8(%ebp),%ebx
|
||||
asm (".byte 0x8b 0x4d 0x0c"); // mov 0xc(%ebp),%ecx
|
||||
asm (".byte 0x8b 0x55 0x10"); // mov 0x10(%ebp),%edx
|
||||
|
||||
asm (".byte 0xb8 0x04 0x00 0x00 0x00"); // mov $0x4,%eax
|
||||
asm (".byte 0xcd 0x80"); // int $0x80
|
||||
}
|
||||
|
||||
void
|
||||
open ()
|
||||
{
|
||||
asm (".byte 0x8b 0x5d 0x08"); // mov 0x8(%ebp),%ebx
|
||||
asm (".byte 0x8b 0x4d 0x0c"); // mov 0xc(%ebp),%ecx
|
||||
asm (".byte 0x8b 0x55 0x10"); // mov 0x10(%ebp),%edx
|
||||
|
||||
asm (".byte 0xb8 0x05 0x00 0x00 0x00"); // mov $0x5,%eax
|
||||
asm (".byte 0xcd 0x80"); // int $0x80
|
||||
}
|
||||
|
||||
void
|
||||
access ()
|
||||
{
|
||||
asm (".byte 0x8b 0x5d 0x08"); // mov 0x8(%ebp),%ebx
|
||||
asm (".byte 0x8b 0x4d 0x0c"); // mov 0xc(%ebp),%ecx
|
||||
|
||||
asm (".byte 0xb8 0x21 0x00 0x00 0x00"); // mov $0x21,%eax
|
||||
asm (".byte 0xcd 0x80"); // int $0x80
|
||||
}
|
||||
|
||||
void
|
||||
brk ()
|
||||
{
|
||||
asm (".byte 0x8b 0x5d 0x08"); // mov 0x8(%ebp),%ebx
|
||||
asm (".byte 0xb8 0x2d 0x00 0x00 0x00"); // mov $0x2d,%eax
|
||||
asm (".byte 0xcd 0x80"); // int $0x80
|
||||
}
|
||||
|
||||
void
|
||||
fsync ()
|
||||
{
|
||||
asm (".byte 0x8b 0x5d 0x08"); // mov 0x8(%ebp),%ebx
|
||||
asm (".byte 0xb8 0x76 0x00 0x00 0x00"); // mov $0x76,%eax
|
||||
asm (".byte 0xcd 0x80"); // int $0x80
|
||||
}
|
||||
|
||||
int
|
||||
strlen (char const* s)
|
||||
{
|
||||
int i = 0;
|
||||
while (s[i]) i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
int
|
||||
eputs (char const* s)
|
||||
{
|
||||
int i = strlen (s);
|
||||
write (2, s, i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
fputs (char const* s, int fd)
|
||||
{
|
||||
int i = strlen (s);
|
||||
write (fd, s, i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
puts (char const* s)
|
||||
{
|
||||
int i = strlen (s);
|
||||
write (1, s, i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
putchar (int c)
|
||||
{
|
||||
write (1, (char*)&c, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
fputc (int c, int fd)
|
||||
{
|
||||
write (fd, (char*)&c, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
assert_fail (char* s)
|
||||
{
|
||||
eputs ("assert fail: ");
|
||||
eputs (s);
|
||||
eputs ("\n");
|
||||
//*((int*)0) = 0;
|
||||
char *fail = s;
|
||||
fail = 0;
|
||||
*fail = 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;
|
||||
}
|
||||
|
||||
//#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;
|
||||
}
|
||||
|
||||
int
|
||||
strcmp (char const* a, char const* b)
|
||||
{
|
||||
while (*a && *b && *a == *b)
|
||||
{
|
||||
a++;b++;
|
||||
}
|
||||
return *a - *b;
|
||||
}
|
||||
|
||||
char *
|
||||
strcpy (char *dest, char const *src)
|
||||
{
|
||||
char *p = dest;
|
||||
while (*src) *p++ = *src++;
|
||||
*p = 0;
|
||||
return dest;
|
||||
}
|
||||
|
||||
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; // FIXME
|
||||
int sign = 0;
|
||||
if (x < 0) sign = 1;
|
||||
if (sign)
|
||||
x = -x;
|
||||
|
||||
do
|
||||
{
|
||||
*p-- = '0' + (x % 10);
|
||||
x = x / 10;
|
||||
} while (x);
|
||||
|
||||
if (sign && *(p + 1) != '0')
|
||||
*p-- = '-';
|
||||
|
||||
return p+1;
|
||||
}
|
||||
|
||||
int
|
||||
isdigit (char c)
|
||||
{
|
||||
//return (c>='0') && (c<='9');
|
||||
if (c>='0' && c<='9') return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
atoi (char const *s)
|
||||
{
|
||||
int i = 0;
|
||||
int sign = 1;
|
||||
if (*s && *s == '-')
|
||||
{
|
||||
sign = -1;
|
||||
s++;
|
||||
}
|
||||
while (isdigit (*s))
|
||||
{
|
||||
i *= 10;
|
||||
i += (*s - '0');
|
||||
s++;
|
||||
}
|
||||
return i * sign;
|
||||
}
|
||||
|
||||
//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;
|
||||
}
|
||||
|
||||
//void *
|
||||
int *
|
||||
//realloc (void *p, int size)
|
||||
realloc (int *p, int size)
|
||||
{
|
||||
brk (g_malloc_base + size);
|
||||
return g_malloc_base;
|
||||
}
|
||||
|
||||
int
|
||||
strncmp (char const* a, char const* b, int length)
|
||||
{
|
||||
while (*a && *b && *a == *b && --length) {a++;b++;}
|
||||
return *a - *b;
|
||||
}
|
||||
|
||||
char **g_environment;
|
||||
char const*
|
||||
getenv (char const* s)
|
||||
{
|
||||
char **p = g_environment;
|
||||
p = *g_environment;
|
||||
int length = strlen (s);
|
||||
while (*p)
|
||||
{
|
||||
if (!strncmp (s, *p, length) && *(*p + length) == '=') return (*p + length + 1);
|
||||
p++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
// !__MESC__
|
||||
// FIXME: mes+nyacc parser bug here
|
||||
// works fine with Guile, but let's keep a single input source
|
||||
|
||||
#define pop_va_arg \
|
||||
asm (".byte 0x8b 0x45 0xfc"); /* mov -<0x4>(%ebp),%eax :va_arg */ \
|
||||
asm (".byte 0xc1 0xe0 0x02"); /* shl $0x2,%eax */ \
|
||||
asm (".byte 0x01 0xe8"); /* add %ebp,%eax */ \
|
||||
asm (".byte 0x83 0xc0 0x0c"); /* add $0xc,%eax */ \
|
||||
asm (".byte 0x8b 0x00"); /* mov (%eax),%eax */ \
|
||||
asm (".byte 0x89 0x45 0xf8"); /* mov %eax,-0x8(%ebp) :va */ \
|
||||
asm (".byte 0x50") /* push %eax */
|
||||
|
||||
#else // __MESC__
|
||||
|
||||
#define pop_va_arg asm (".byte 0x8b 0x45 0xfc 0xc1 0xe0 0x02 0x01 0xe8 0x83 0xc0 0x0c 0x8b 0x00 0x89 0x45 0xf8 0x50")
|
||||
|
||||
#endif
|
||||
|
||||
int
|
||||
printf (char const* format, int va_args)
|
||||
{
|
||||
int va_arg = 0;
|
||||
int va;
|
||||
char *p = format;
|
||||
while (*p)
|
||||
if (*p != '%')
|
||||
putchar (*p++);
|
||||
else
|
||||
{
|
||||
p++;
|
||||
char c = *p;
|
||||
switch (c)
|
||||
{
|
||||
case '%': {putchar (*p); break;}
|
||||
case 'c': {pop_va_arg; putchar ((char)va); va_arg++; break;}
|
||||
case 'd': {pop_va_arg; puts (itoa (va)); va_arg++; break;}
|
||||
case 's': {pop_va_arg; puts ((char*)va); va_arg++; break;}
|
||||
default: putchar (*p);
|
||||
}
|
||||
p++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char **g_environment;
|
||||
char **
|
||||
_env (char **e)
|
||||
{
|
||||
return e;
|
||||
}
|
||||
|
||||
int
|
||||
_start ()
|
||||
{
|
||||
asm (".byte 0x89 0xe8"); // mov %ebp,%eax
|
||||
asm (".byte 0x83 0xc0 0x08"); // add $0x8,%eax
|
||||
asm (".byte 0x50"); // push %eax
|
||||
|
||||
asm (".byte 0x89 0xe8"); // mov %ebp,%eax
|
||||
asm (".byte 0x83 0xc0 0x04"); // add $0x4,%eax
|
||||
asm (".byte 0x0f 0xb6 0x00"); // movzbl (%eax),%eax
|
||||
asm (".byte 0x50"); // push %eax
|
||||
|
||||
asm (".byte 0x89 0xe8"); // mov %ebp,%eax
|
||||
asm (".byte 0x83 0xc0 0x04"); // add $0x4,%eax
|
||||
asm (".byte 0x0f 0xb6 0x00"); // movzbl (%eax),%eax
|
||||
asm (".byte 0x83 0xc0 0x03"); // add $0x3,%eax
|
||||
asm (".byte 0xc1 0xe0 0x02"); // shl $0x2,%eax
|
||||
asm (".byte 0x01 0xe8"); // add %ebp,%eax
|
||||
asm (".byte 0x50"); // push %eax
|
||||
|
||||
g_environment = _env ();
|
||||
asm (".byte 0x58");
|
||||
int r = main ();
|
||||
exit (r);
|
||||
}
|
87
libc/mini-libc-mes.c
Normal file
87
libc/mini-libc-mes.c
Normal file
|
@ -0,0 +1,87 @@
|
|||
/* -*-comment-start: "//";comment-end:""-*-
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
void
|
||||
exit ()
|
||||
{
|
||||
asm (".byte 0x8b 0x5d 0x08"); // mov 0x8(%ebp),%ebx
|
||||
asm (".byte 0xb8 0x01 0x00 0x00 0x00"); // mov $0x1,%eax
|
||||
asm (".byte 0xcd 0x80"); // int $0x80
|
||||
}
|
||||
|
||||
void
|
||||
write ()
|
||||
{
|
||||
asm (".byte 0x8b 0x5d 0x08"); // mov 0x8(%ebp),%ebx
|
||||
asm (".byte 0x8b 0x4d 0x0c"); // mov 0xc(%ebp),%ecx
|
||||
asm (".byte 0x8b 0x55 0x10"); // mov 0x10(%ebp),%edx
|
||||
|
||||
asm (".byte 0xb8 0x04 0x00 0x00 0x00"); // mov $0x4,%eax
|
||||
asm (".byte 0xcd 0x80"); // int $0x80
|
||||
}
|
||||
|
||||
int
|
||||
strlen (char const* s)
|
||||
{
|
||||
int i = 0;
|
||||
while (s[i]) i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
int
|
||||
eputs (char const* s)
|
||||
{
|
||||
int i = strlen (s);
|
||||
write (2, s, i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char **g_environment;
|
||||
char **
|
||||
_env (char **e)
|
||||
{
|
||||
return e;
|
||||
}
|
||||
|
||||
int
|
||||
_start ()
|
||||
{
|
||||
asm (".byte 0x89 0xe8"); // mov %ebp,%eax
|
||||
asm (".byte 0x83 0xc0 0x08"); // add $0x8,%eax
|
||||
asm (".byte 0x50"); // push %eax
|
||||
|
||||
asm (".byte 0x89 0xe8"); // mov %ebp,%eax
|
||||
asm (".byte 0x83 0xc0 0x04"); // add $0x4,%eax
|
||||
asm (".byte 0x0f 0xb6 0x00"); // movzbl (%eax),%eax
|
||||
asm (".byte 0x50"); // push %eax
|
||||
|
||||
asm (".byte 0x89 0xe8"); // mov %ebp,%eax
|
||||
asm (".byte 0x83 0xc0 0x04"); // add $0x4,%eax
|
||||
asm (".byte 0x0f 0xb6 0x00"); // movzbl (%eax),%eax
|
||||
asm (".byte 0x83 0xc0 0x03"); // add $0x3,%eax
|
||||
asm (".byte 0xc1 0xe0 0x02"); // shl $0x2,%eax
|
||||
asm (".byte 0x01 0xe8"); // add %ebp,%eax
|
||||
asm (".byte 0x50"); // push %eax
|
||||
|
||||
g_environment = _env ();
|
||||
asm (".byte 0x58");
|
||||
int r = main ();
|
||||
exit (r);
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
/* -*-comment-start: "//";comment-end:""-*-
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#if __GNUC__
|
||||
void
|
||||
_start ()
|
||||
{
|
||||
// char **;
|
||||
asm (
|
||||
"mov %%ebp,%%eax\n\t"
|
||||
"addl $4,%%eax\n\t"
|
||||
"movzbl (%%eax),%%eax\n\t"
|
||||
"addl $3,%%eax\n\t"
|
||||
"shl $2,%%eax\n\t"
|
||||
"add %%ebp,%%eax\n\t"
|
||||
"movl %%eax,%0\n\t"
|
||||
: "=g_environment" (g_environment)
|
||||
: //no inputs ""
|
||||
);
|
||||
int r;
|
||||
asm (
|
||||
"mov %%ebp,%%eax\n\t"
|
||||
"addl $8,%%eax\n\t"
|
||||
"push %%eax\n\t"
|
||||
|
||||
"mov %%ebp,%%eax\n\t"
|
||||
"addl $4,%%eax\n\t"
|
||||
"movzbl (%%eax),%%eax\n\t"
|
||||
"push %%eax\n\t"
|
||||
|
||||
"call main\n\t"
|
||||
"movl %%eax,%0\n\t"
|
||||
: "=r" (r)
|
||||
: //no inputs ""
|
||||
);
|
||||
exit (r);
|
||||
}
|
||||
#endif // __GNUC__
|
|
@ -1,4 +1,4 @@
|
|||
C_FLAGS:=-nostdinc --include mstart.c -fno-builtin
|
||||
C_FLAGS:=-nostdinc -fno-builtin
|
||||
LD_FLAGS:=-nostdlib
|
||||
CROSS:=$(CC32:%gcc=%)
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ ifneq ($(DEBUG),)
|
|||
$(info TARGET=$(TARGET))
|
||||
$(info C_FILES=$(C_FILES))
|
||||
$(info O_FILES=$(O_FILES))
|
||||
$(info O_FILES=$(D_FILES))
|
||||
$(info D_FILES=$(D_FILES))
|
||||
endif
|
||||
|
||||
CLEAN+=$(O_FILES) $(OUT)/$(TARGET)
|
||||
|
@ -19,7 +19,7 @@ $(OUT)/$(TARGET): CC:=$(CROSS)$(CC)
|
|||
$(OUT)/$(TARGET): LDFLAGS:=$(LDFLAGS) $(LD_FLAGS) $(LINK)
|
||||
$(OUT)/$(TARGET): O_FILES:=$(O_FILES)
|
||||
$(OUT)/$(TARGET): $(O_FILES)
|
||||
@echo " $(ld) $(notdir $^) -> $(notdir $@)"
|
||||
@echo " $(ld) $(notdir $^) -> $(notdir $@)"
|
||||
$(QUIET)$(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@
|
||||
|
||||
include make/compile.make
|
||||
|
|
|
@ -2,7 +2,9 @@ ifeq ($(TEST),)
|
|||
TEST:=$(TARGET)-check
|
||||
$(TEST): EXT:=$(EXT)
|
||||
$(TEST): EXPECT:=$(EXPECT)
|
||||
$(TEST): SHELL:=$(SHELL)
|
||||
$(TEST): $(OUT)/$(TARGET)
|
||||
@export SHELL=$(SHELL)
|
||||
ifeq ($(EXPECT),)
|
||||
$< - arg1 arg2 arg3 arg4 > $(<:.$(EXT)=.stdout)
|
||||
else
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
ifeq ($(TEST),)
|
||||
TEST:=$(TARGET)-check
|
||||
$(TEST): EXPECT:=$(EXPECT)
|
||||
$(TEST): SHELL:=$(SHELL)
|
||||
$(TEST): $(OUT)/$(TARGET)
|
||||
@export SHELL=$(SHELL)
|
||||
ifeq ($(EXPECT),)
|
||||
$<
|
||||
else
|
||||
|
|
|
@ -5,7 +5,7 @@ $(OUT)/$(1:.c=.$(CROSS)o): CC:=$(CROSS)$(CC)
|
|||
$(OUT)/$(1:.c=.$(CROSS)o): CPPFLAGS:=$$(CPPFLAGS) $$(CPP_FLAGS) $(2:%=-D%) $(3:%=-I%)
|
||||
$(OUT)/$(1:.c=.$(CROSS)o): CFLAGS:=$$(CFLAGS) $$(C_FLAGS)
|
||||
$(OUT)/$(1:.c=.$(CROSS)o): $(1)
|
||||
@echo " $$(cc) $$(notdir $$<) -> $$(notdir $$@)"
|
||||
@echo " $$(cc) $$(notdir $$<) -> $$(notdir $$@)"
|
||||
@mkdir -p $$(dir $$@)
|
||||
$$(QUIET)$$(COMPILE.c) $$(OUTPUT_OPTION) -MMD -MF $$(@:%.$(CROSS)o=%.$(CROSS)d) -MT '$$(@:.%$(CROSS)o=%.$(CROSS)d)' $$<
|
||||
endef
|
||||
|
|
|
@ -1,10 +1,51 @@
|
|||
CROSS:=guile-
|
||||
C_FILES:=libc/libc-mes.c $(C_FILES)
|
||||
#C_FILES:=libc/mini-libc-mes.c $(C_FILES)
|
||||
O_FILES:=$(C_FILES:%.c=$(OUT)/%.$(CROSS)o)
|
||||
|
||||
ifneq ($(DEBUG),)
|
||||
$(info TARGET=$(TARGET))
|
||||
$(info C_FILES=$(C_FILES))
|
||||
$(info O_FILES=$(O_FILES))
|
||||
endif
|
||||
|
||||
CLEAN+=$(O_FILES) $(OUT)/$(TARGET)
|
||||
|
||||
CLEAN+=$(OUT)/$(TARGET)
|
||||
$(OUT)/$(TARGET): C_INCLUDE_PATH:=$(INCLUDES)
|
||||
$(OUT)/$(TARGET): $(MAKEFILE_LIST)
|
||||
$(OUT)/$(TARGET): $(INSTALL_GO_FILES)
|
||||
$(OUT)/$(TARGET): $(C_FILES)
|
||||
@echo " mescc.scm $(notdir $<) -> $(notdir $@)"
|
||||
@rm -f $@
|
||||
$(QUIET) guile/mescc.scm $(C_INCLUDE_PATH:%=-I %) -o $@ $< || rm -f $@
|
||||
@[ -f $@ ] && chmod +x $@ ||:
|
||||
|
||||
INCLUDES+=libc/include libc $(OUT)/$(DIR)
|
||||
MESCC.scm:=guile/mescc.scm
|
||||
MESLD.scm:=guile/mescc.scm
|
||||
|
||||
$(OUT)/$(TARGET): ld:=MESLD.scm
|
||||
$(OUT)/$(TARGET): LD:=$(MESLD.scm)
|
||||
$(OUT)/$(TARGET): CC:=$(MESCC.scm)
|
||||
$(OUT)/$(TARGET): CFLAGS:=
|
||||
$(OUT)/$(TARGET): LDFLAGS:=
|
||||
$(OUT)/$(TARGET): O_FILES:=$(O_FILES)
|
||||
$(OUT)/$(TARGET): $(O_FILES)
|
||||
@echo " $(ld) $(notdir $(O_FILES)) -> $(notdir $@)"
|
||||
$(QUIET)$(LINK.c) $(O_FILES) $(LOADLIBES) $(LDLIBS) -o $@
|
||||
|
||||
define mescc.scm-c-compile
|
||||
$(OUT)/$(1:.c=.$(CROSS)o): $(MAKEFILE_LIST)
|
||||
$(OUT)/$(1:.c=.$(CROSS)o): cc:=MESCC.scm
|
||||
$(OUT)/$(1:.c=.$(CROSS)o): CC:=$(MESCC.scm)
|
||||
$(OUT)/$(1:.c=.$(CROSS)o): CPPFLAGS:=$(2:%=-D %) $(3:%=-I %)
|
||||
$(OUT)/$(1:.c=.$(CROSS)o): COMPILE.c:=$(MESCC.scm) -c $(CPPFLAGS)
|
||||
$(OUT)/$(1:.c=.$(CROSS)o): $(INSTALL_GO_FILES)
|
||||
$(OUT)/$(1:.c=.$(CROSS)o): $(1)
|
||||
@echo " $$(cc) $$(notdir $(1)) -> $$(notdir $$@)"
|
||||
@mkdir -p $$(dir $$@)
|
||||
$$(QUIET)$$(COMPILE.c) $$(CPPFLAGS) $$(OUTPUT_OPTION) $(1)
|
||||
endef
|
||||
|
||||
ifeq ($(MLIBC.scm),)
|
||||
MLIBC.scm:=DONE
|
||||
else
|
||||
C_FILES:=$(filter-out libc/libc-mes.c,$(C_FILES))
|
||||
C_FILES:=$(filter-out libc/mini-libc-mes.c,$(C_FILES))
|
||||
endif
|
||||
$(foreach c-file,$(strip $(filter %.c,$(C_FILES))),$(eval $(call mescc.scm-c-compile,$(c-file),$(DEFINES),$(INCLUDES))))
|
||||
|
||||
include make/reset.make
|
||||
|
|
|
@ -1,16 +1,52 @@
|
|||
CLEAN+=$(OUT)/$(TARGET)
|
||||
ifneq ($(MES_MAX_ARENA),)
|
||||
$(OUT)/$(TARGET): MES_MAX_ARENA-flag:=MES_MAX_ARENA=$(MES_MAX_ARENA)
|
||||
CROSS:=mes-
|
||||
C_FILES:=libc/libc-mes.c $(C_FILES)
|
||||
O_FILES:=$(C_FILES:%.c=$(OUT)/%.$(CROSS)o)
|
||||
|
||||
ifneq ($(DEBUG),)
|
||||
$(info TARGET=$(TARGET))
|
||||
$(info C_FILES=$(C_FILES))
|
||||
$(info O_FILES=$(O_FILES))
|
||||
endif
|
||||
$(OUT)/$(TARGET): C_INCLUDE_PATH:=$(INCLUDES)
|
||||
$(OUT)/$(TARGET): $(MAKEFILE_LIST)
|
||||
$(OUT)/$(TARGET): module/mes/read-0.mo
|
||||
$(OUT)/$(TARGET): module/mes/read-0-32.mo
|
||||
$(OUT)/$(TARGET): $(INSTALL_MES_FILES)
|
||||
$(OUT)/$(TARGET): scripts/mes
|
||||
$(OUT)/$(TARGET): $(C_FILES)
|
||||
@echo " mescc.mes $(notdir $<) -> $(notdir $@)"
|
||||
@rm -f $@
|
||||
$(QUIET)MES_DEBUG=$(MES_DEBUG) $(MES_MAX_ARENA-flag) MES_FLAGS=--load scripts/mescc.mes $(C_INCLUDE_PATH:%=-I %) -o $@ $< || rm -f $@
|
||||
@[ -f $@ ] && chmod +x $@ ||:
|
||||
|
||||
CLEAN+=$(O_FILES) $(OUT)/$(TARGET)
|
||||
|
||||
CLEAN+=$(OUT)/$(TARGET)
|
||||
|
||||
INCLUDES+=libc/include libc $(OUT)/$(DIR)
|
||||
MESCC.mes:=scripts/mescc.mes
|
||||
MESLD.mes:=scripts/mescc.mes
|
||||
|
||||
$(OUT)/$(TARGET): ld:=MESLD.mes
|
||||
$(OUT)/$(TARGET): LD:=$(MESLD.mes)
|
||||
$(OUT)/$(TARGET): CC:=$(MESCC.mes)
|
||||
$(OUT)/$(TARGET): CFLAGS:=
|
||||
$(OUT)/$(TARGET): LDFLAGS:=
|
||||
$(OUT)/$(TARGET): O_FILES:=$(O_FILES)
|
||||
$(OUT)/$(TARGET): $(O_FILES)
|
||||
@echo " $(ld) $(notdir $(O_FILES)) -> $(notdir $@)"
|
||||
$(QUIET)$(LINK.c) $(O_FILES) $(LOADLIBES) $(LDLIBS) -o $@
|
||||
|
||||
define mescc.mes-c-compile
|
||||
$(OUT)/$(1:.c=.$(CROSS)o): $(MAKEFILE_LIST)
|
||||
$(OUT)/$(1:.c=.$(CROSS)o): cc:=MESCC.mes
|
||||
$(OUT)/$(1:.c=.$(CROSS)o): CC:=$(MESCC.mes)
|
||||
$(OUT)/$(1:.c=.$(CROSS)o): COMPILE.c:=$(MESCC.mes) -c
|
||||
$(OUT)/$(1:.c=.$(CROSS)o): CPPFLAGS:=$(2:%=-D %) $(3:%=-I %)
|
||||
$(OUT)/$(1:.c=.$(CROSS)o): COMPILE.c:=$(MESCC.mes) -c $(CPPFLAGS)
|
||||
$(OUT)/$(1:.c=.$(CROSS)o): all-mo
|
||||
$(OUT)/$(1:.c=.$(CROSS)o): $(INSTALL_MES_FILES)
|
||||
$(OUT)/$(1:.c=.$(CROSS)o): $(1)
|
||||
@echo " $$(cc) $$(notdir $(1)) -> $$(notdir $$@)"
|
||||
@mkdir -p $$(dir $$@)
|
||||
$$(QUIET)$$(COMPILE.c) $$(OUTPUT_OPTION) $(1)
|
||||
endef
|
||||
|
||||
ifeq ($(MLIBC.mes),)
|
||||
MLIBC.mes:=DONE
|
||||
else
|
||||
C_FILES:=$(filter-out libc/libc-mes.c,$(C_FILES))
|
||||
endif
|
||||
|
||||
$(foreach c-file,$(strip $(filter %.c,$(C_FILES))),$(eval $(call mescc.mes-c-compile,$(c-file),$(DEFINES),$(INCLUDES))))
|
||||
|
||||
include make/reset.make
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
(mes-use-module (mes elf-util))
|
||||
(mes-use-module (mes elf))
|
||||
(mes-use-module (mes as-i386))
|
||||
(mes-use-module (mes libc))
|
||||
(mes-use-module (mes optargs))))
|
||||
|
||||
(define (logf port string . rest)
|
||||
|
@ -1149,7 +1148,7 @@
|
|||
(or (assoc-ref (.locals info) o)
|
||||
(assoc-ref (.globals info) o)
|
||||
(begin
|
||||
(stderr "NO IDENT: ~a\n" (assoc-ref (.functions info) o))
|
||||
(stderr "NO IDENT: ~a\n" o)
|
||||
(assoc-ref (.functions info) o))))
|
||||
|
||||
(define (ident->type info o)
|
||||
|
@ -1261,6 +1260,12 @@
|
|||
|
||||
((compd-stmt (block-item-list . ,statements)) ((ast-list->info info) statements))
|
||||
|
||||
((expr-stmt (fctn-call (p-expr (ident ,name)) (expr-list . ,expr-list)))
|
||||
(if (equal? name "asm") (let ((arg0 (cadr (cadar expr-list))))
|
||||
(append-text info (wrap-as (asm->hex arg0))))
|
||||
(let ((info ((expr->accu info) `(fctn-call (p-expr (ident ,name)) (expr-list . ,expr-list)))))
|
||||
(append-text info (wrap-as (i386:accu-zero?))))))
|
||||
|
||||
((if ,test ,body)
|
||||
(let* ((text-length (length text))
|
||||
|
||||
|
@ -2161,18 +2166,11 @@
|
|||
|
||||
(define* (c99-input->info #:key (defines '()) (includes '()))
|
||||
(lambda ()
|
||||
(let* ((info (make <info>
|
||||
#:functions i386:libc
|
||||
#:types i386:type-alist))
|
||||
(foo (stderr "compiling: mlibc\n"))
|
||||
(info (let loop ((info info) (libc libc))
|
||||
(if (null? libc) info
|
||||
(loop ((ast->info info) ((car libc))) (cdr libc)))))
|
||||
(let* ((info (make <info> #:types i386:type-alist))
|
||||
(foo (stderr "parsing: input\n"))
|
||||
(ast (c99-input->ast #:defines defines #:includes includes))
|
||||
(foo (stderr "compiling: input\n"))
|
||||
(info ((ast->info info) ast))
|
||||
(info ((ast->info info) (_start)))
|
||||
(info (clone info #:text '() #:locals '())))
|
||||
info)))
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
;;; Commentary:
|
||||
|
||||
;;; libc-i386.mes defines i386 assembly
|
||||
;;; as-i386.mes defines i386 assembly
|
||||
|
||||
;;; Code:
|
||||
|
||||
|
|
|
@ -1,170 +0,0 @@
|
|||
;;; -*-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-i386.mes defines C library routines
|
||||
|
||||
;;; Code:
|
||||
|
||||
(define i386:exit
|
||||
'(lambda (f g ta t d)
|
||||
(list
|
||||
#x5b ; pop %ebx
|
||||
#x5b ; pop %ebx
|
||||
#xb8 #x01 #x00 #x00 #x00 ; mov $0x1,%eax
|
||||
#xcd #x80 ; int $0x80
|
||||
)))
|
||||
|
||||
(define i386:read
|
||||
'(lambda (f g ta t d)
|
||||
(list
|
||||
#x55 ; push %ebp
|
||||
#x89 #xe5 ; mov %esp,%ebp
|
||||
|
||||
#x8b #x5d #x08 ; mov 0x8(%ebp),%ebx
|
||||
#x8b #x4d #x0c ; mov 0xc(%ebp),%ecx
|
||||
#x8b #x55 #x10 ; mov 0x10(%ebp),%edx
|
||||
|
||||
#xb8 #x03 #x00 #x00 #x00 ; mov $0x3,%eax
|
||||
#xcd #x80 ; int $0x80
|
||||
|
||||
#xc9 ; leave
|
||||
#xc3 ; ret
|
||||
)))
|
||||
|
||||
(define i386:write
|
||||
'(lambda (f g ta t d)
|
||||
(list
|
||||
#x55 ; push %ebp
|
||||
#x89 #xe5 ; mov %esp,%ebp
|
||||
|
||||
#x8b #x5d #x08 ; mov 0x8(%ebp),%ebx
|
||||
#x8b #x4d #x0c ; mov 0xc(%ebp),%ecx
|
||||
#x8b #x55 #x10 ; mov 0x10(%ebp),%edx
|
||||
|
||||
#xb8 #x04 #x00 #x00 #x00 ; mov $0x4,%eax
|
||||
#xcd #x80 ; int $0x80
|
||||
|
||||
#xc9 ; leave
|
||||
#xc3 ; ret
|
||||
)))
|
||||
|
||||
(define i386:open
|
||||
'(lambda (f g ta t d)
|
||||
(list
|
||||
#x55 ; push %ebp
|
||||
#x89 #xe5 ; mov %esp,%ebp
|
||||
|
||||
#x8b #x5d #x08 ; mov 0x8(%ebp),%ebx
|
||||
#x8b #x4d #x0c ; mov 0xc(%ebp),%ecx
|
||||
#x8b #x55 #x10 ; mov 0x10(%ebp),%edx
|
||||
|
||||
#xb8 #x05 #x00 #x00 #x00 ; mov $0x5,%eax
|
||||
#xcd #x80 ; int $0x80
|
||||
|
||||
#xc9 ; leave
|
||||
#xc3 ; ret
|
||||
)))
|
||||
|
||||
(define i386:access
|
||||
'(lambda (f g ta t d)
|
||||
(list
|
||||
#x55 ; push %ebp
|
||||
#x89 #xe5 ; mov %esp,%ebp
|
||||
|
||||
#x8b #x5d #x08 ; mov 0x8(%ebp),%ebx
|
||||
#x8b #x4d #x0c ; mov 0xc(%ebp),%ecx
|
||||
|
||||
#xb8 #x21 #x00 #x00 #x00 ; mov $0x21,%eax
|
||||
#xcd #x80 ; int $0x80
|
||||
|
||||
#xc9 ; leave
|
||||
#xc3 ; ret
|
||||
)))
|
||||
|
||||
(define i386:brk
|
||||
'(lambda (f g ta t d)
|
||||
(list
|
||||
#x55 ; push %ebp
|
||||
#x89 #xe5 ; mov %esp,%ebp
|
||||
|
||||
#x8b #x5d #x08 ; mov 0x8(%ebp),%ebx
|
||||
#xb8 #x2d #x00 #x00 #x00 ; mov $0x2d,%eax
|
||||
#xcd #x80 ; int $0x80
|
||||
|
||||
#xc9 ; leave
|
||||
#xc3 ; ret
|
||||
)))
|
||||
|
||||
(define i386:fsync
|
||||
'(lambda (f g ta t d)
|
||||
(list
|
||||
#x55 ; push %ebp
|
||||
#x89 #xe5 ; mov %esp,%ebp
|
||||
|
||||
#x8b #x5d #x08 ; mov 0x8(%ebp),%ebx
|
||||
#xb8 #x76 #x00 #x00 #x00 ; mov $0x76,%eax
|
||||
#xcd #x80 ; int $0x80
|
||||
|
||||
#xc9 ; leave
|
||||
#xc3 ; ret
|
||||
)))
|
||||
|
||||
(define (i386:_start)
|
||||
(string-append ".byte"
|
||||
" 0x89 0xe8" ; mov %ebp,%eax
|
||||
" 0x83 0xc0 0x08" ; add $0x8,%eax
|
||||
" 0x50" ; push %eax
|
||||
|
||||
" 0x89 0xe8" ; mov %ebp,%eax
|
||||
" 0x83 0xc0 0x04" ; add $0x4,%eax
|
||||
" 0x0f 0xb6 0x00" ; movzbl (%eax),%eax
|
||||
" 0x50" ; push %eax
|
||||
|
||||
" 0x89 0xe8" ; mov %ebp,%eax
|
||||
" 0x83 0xc0 0x04" ; add $0x4,%eax
|
||||
" 0x0f 0xb6 0x00" ; movzbl (%eax),%eax
|
||||
" 0x83 0xc0 0x03" ; add $0x3,%eax
|
||||
" 0xc1 0xe0 0x02" ; shl $0x2,%eax
|
||||
" 0x01 0xe8" ; add %ebp,%eax
|
||||
" 0x50" ; push %eax
|
||||
))
|
||||
|
||||
(define (i386:va-arg)
|
||||
(string-append ".byte"
|
||||
" 0x8b 0x45 0xfc" ; mov -<0x4>(%ebp),%eax :va_arg
|
||||
" 0xc1 0xe0 0x2" ; shl $0x2,%eax
|
||||
" 0x01 0xe8" ; add %ebp,%eax
|
||||
" 0x83 0xc0 0xc" ; add $0xc,%eax
|
||||
" 0x8b 0x00" ; mov (%eax),%eax
|
||||
" 0x89 0x45 0xf8" ; mov %eax,-0x8(%ebp) :va
|
||||
" 0x50" ; push %eax
|
||||
))
|
||||
|
||||
(define i386:libc
|
||||
(list
|
||||
(cons "exit" (list i386:exit))
|
||||
(cons "read" (list i386:read))
|
||||
(cons "write" (list i386:write))
|
||||
(cons "open" (list i386:open))
|
||||
(cons "access" (list i386:access))
|
||||
(cons "brk" (list i386:brk))
|
||||
(cons "fsync" (list i386:fsync))))
|
|
@ -1,32 +0,0 @@
|
|||
;;; -*-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-i386.mes defines C library routines
|
||||
|
||||
;;; Code:
|
||||
|
||||
(define-module (mes libc-i386)
|
||||
#:export (i386:libc
|
||||
i386:_start
|
||||
i386:va-arg))
|
||||
|
||||
(include-from-path "mes/libc-i386.mes")
|
|
@ -1,421 +0,0 @@
|
|||
;;; -*-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)))
|
||||
(format (current-error-port) "parsing: _start\n")
|
||||
(with-input-from-string
|
||||
(string-append "
|
||||
char **g_environment;
|
||||
char **
|
||||
_env (char **e)
|
||||
{
|
||||
return e;
|
||||
}
|
||||
|
||||
int
|
||||
_start ()
|
||||
{
|
||||
asm(\"" argc-argv "\");
|
||||
g_environment = _env ();
|
||||
asm (\".byte 0x58\");
|
||||
int r = main ();
|
||||
exit (r);
|
||||
}
|
||||
") parse-c99)))
|
||||
|
||||
(define (strlen)
|
||||
(format (current-error-port) "parsing: strlen\n")
|
||||
(with-input-from-string
|
||||
"
|
||||
int
|
||||
strlen (char const* s)
|
||||
{
|
||||
int i = 0;
|
||||
while (s[i]) i++;
|
||||
return i;
|
||||
}
|
||||
" parse-c99))
|
||||
|
||||
(define (getchar)
|
||||
(format (current-error-port) "parsing: getchar\n")
|
||||
(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;
|
||||
}
|
||||
" parse-c99))
|
||||
|
||||
(define (assert_fail)
|
||||
(format (current-error-port) "parsing: assert_fail\n")
|
||||
(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;
|
||||
}
|
||||
" parse-c99))
|
||||
|
||||
(define (ungetc)
|
||||
(format (current-error-port) "parsing: ungetc\n")
|
||||
(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;
|
||||
}
|
||||
" parse-c99))
|
||||
|
||||
(define (putchar)
|
||||
(format (current-error-port) "parsing: putchar\n")
|
||||
(with-input-from-string
|
||||
"
|
||||
int
|
||||
putchar (int c)
|
||||
{
|
||||
write (1, (char*)&c, 1);
|
||||
return 0;
|
||||
}
|
||||
" parse-c99))
|
||||
|
||||
(define (fputc)
|
||||
(format (current-error-port) "parsing: fputc\n")
|
||||
(with-input-from-string
|
||||
"
|
||||
int
|
||||
fputc (int c, int fd)
|
||||
{
|
||||
write (fd, (char*)&c, 1);
|
||||
return 0;
|
||||
}
|
||||
" parse-c99))
|
||||
|
||||
(define (eputs)
|
||||
(format (current-error-port) "parsing: eputs\n")
|
||||
(with-input-from-string
|
||||
"
|
||||
int
|
||||
eputs (char const* s)
|
||||
{
|
||||
int i = strlen (s);
|
||||
write (2, s, i);
|
||||
return 0;
|
||||
}
|
||||
" parse-c99))
|
||||
|
||||
|
||||
(define (fputs)
|
||||
(format (current-error-port) "parsing: fputs\n")
|
||||
(with-input-from-string
|
||||
"
|
||||
int
|
||||
fputs (char const* s, int fd)
|
||||
{
|
||||
int i = strlen (s);
|
||||
write (fd, s, i);
|
||||
return 0;
|
||||
}
|
||||
" parse-c99))
|
||||
|
||||
(define (puts)
|
||||
(format (current-error-port) "parsing: puts\n")
|
||||
(with-input-from-string
|
||||
"
|
||||
int
|
||||
puts (char const* s)
|
||||
{
|
||||
int i = strlen (s);
|
||||
write (1, s, i);
|
||||
return 0;
|
||||
}
|
||||
" parse-c99))
|
||||
|
||||
(define (strcmp)
|
||||
(format (current-error-port) "parsing: strcmp\n")
|
||||
(with-input-from-string
|
||||
"
|
||||
int
|
||||
strcmp (char const* a, char const* b)
|
||||
{
|
||||
while (*a && *b && *a == *b)
|
||||
{
|
||||
a++;b++;
|
||||
}
|
||||
return *a - *b;
|
||||
}
|
||||
" parse-c99))
|
||||
|
||||
(define (strcpy)
|
||||
(format (current-error-port) "parsing: strcpy\n")
|
||||
(with-input-from-string
|
||||
"
|
||||
char *
|
||||
strcpy (char *dest, char const *src)
|
||||
{
|
||||
char *p = dest;
|
||||
while (*src) *p++ = *src++;
|
||||
*p = 0;
|
||||
return dest;
|
||||
}
|
||||
" parse-c99))
|
||||
|
||||
(define (itoa)
|
||||
(format (current-error-port) "parsing: itoa\n")
|
||||
(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; // FIXME
|
||||
int sign = 0;
|
||||
if (x < 0) sign = 1;
|
||||
if (sign)
|
||||
x = -x;
|
||||
|
||||
do
|
||||
{
|
||||
*p-- = '0' + (x % 10);
|
||||
x = x / 10;
|
||||
} while (x);
|
||||
|
||||
if (sign && *(p + 1) != '0')
|
||||
*p-- = '-';
|
||||
|
||||
return p+1;
|
||||
}
|
||||
" parse-c99))
|
||||
|
||||
(define (isdigit)
|
||||
(format (current-error-port) "parsing: isdigit\n")
|
||||
(with-input-from-string
|
||||
"
|
||||
int
|
||||
isdigit (char c)
|
||||
{
|
||||
//return (c>='0') && (c<='9');
|
||||
if (c>='0' && c<='9') return 1;
|
||||
return 0;
|
||||
}
|
||||
" parse-c99))
|
||||
|
||||
(define (atoi)
|
||||
(format (current-error-port) "parsing: atoi\n")
|
||||
(with-input-from-string
|
||||
"
|
||||
int
|
||||
atoi (char const *s)
|
||||
{
|
||||
int i = 0;
|
||||
int sign = 1;
|
||||
if (*s && *s == '-')
|
||||
{
|
||||
sign = -1;
|
||||
s++;
|
||||
}
|
||||
while (isdigit (*s))
|
||||
{
|
||||
i *= 10;
|
||||
i += (*s - '0');
|
||||
s++;
|
||||
}
|
||||
return i * sign;
|
||||
}
|
||||
" parse-c99))
|
||||
|
||||
(define (malloc)
|
||||
(format (current-error-port) "parsing: malloc\n")
|
||||
(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;
|
||||
}
|
||||
" parse-c99))
|
||||
|
||||
(define (realloc)
|
||||
(format (current-error-port) "parsing: realloc\n")
|
||||
(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;
|
||||
}
|
||||
" parse-c99))
|
||||
|
||||
(define (strncmp)
|
||||
(format (current-error-port) "parsing: strncmp\n")
|
||||
(with-input-from-string
|
||||
"
|
||||
int
|
||||
strncmp (char const* a, char const* b, int length)
|
||||
{
|
||||
while (*a && *b && *a == *b && --length) {a++;b++;}
|
||||
return *a - *b;
|
||||
}
|
||||
" parse-c99))
|
||||
|
||||
(define (c:getenv)
|
||||
(format (current-error-port) "parsing: getenv\n")
|
||||
(with-input-from-string
|
||||
"
|
||||
char **g_environment;
|
||||
char const*
|
||||
getenv (char const* s)
|
||||
{
|
||||
char **p = g_environment;
|
||||
p = *g_environment;
|
||||
int length = strlen (s);
|
||||
while (*p)
|
||||
{
|
||||
if (!strncmp (s, *p, length) && *(*p + length) == '=') return (*p + length + 1);
|
||||
p++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
" parse-c99))
|
||||
|
||||
(define (printf)
|
||||
(format (current-error-port) "parsing: printf\n")
|
||||
(let ((va-arg (i386:va-arg)))
|
||||
(with-input-from-string
|
||||
(string-append "
|
||||
int
|
||||
printf (char const* format, int va_args)
|
||||
{
|
||||
int va_arg = 0;
|
||||
int va;
|
||||
char *p = format;
|
||||
while (*p)
|
||||
if (*p != '%')
|
||||
putchar (*p++);
|
||||
else
|
||||
{
|
||||
p++;
|
||||
char c = *p;
|
||||
switch (c)
|
||||
{
|
||||
case '%': {putchar (*p); break;}
|
||||
case 'c': {asm (\"" va-arg "\"); putchar ((char)va); va_arg++; break;}
|
||||
case 'd': {asm (\"" va-arg "\"); puts (itoa (va)); va_arg++; break;}
|
||||
case 's': {asm (\"" va-arg "\"); puts ((char*)va); va_arg++; break;}
|
||||
default: putchar (*p);
|
||||
}
|
||||
p++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
") parse-c99)))
|
||||
|
||||
(define libc
|
||||
(list
|
||||
strlen
|
||||
getchar
|
||||
assert_fail
|
||||
ungetc
|
||||
putchar
|
||||
fputc
|
||||
eputs
|
||||
fputs
|
||||
puts
|
||||
strcmp
|
||||
strcpy
|
||||
itoa
|
||||
isdigit
|
||||
atoi
|
||||
malloc
|
||||
realloc
|
||||
strncmp
|
||||
c:getenv
|
||||
printf
|
||||
))
|
|
@ -1,36 +0,0 @@
|
|||
;;; -*-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:
|
||||
|
||||
;;; Code:
|
||||
|
||||
(define-module (mes libc)
|
||||
#:use-module (nyacc lang c99 parser)
|
||||
#:use-module (mes libc-i386)
|
||||
#:export (libc _start))
|
||||
|
||||
(cond-expand
|
||||
(guile-2)
|
||||
(guile
|
||||
(use-modules (ice-9 syncase)))
|
||||
(mes))
|
||||
|
||||
(include-from-path "mes/libc.mes")
|
|
@ -18,7 +18,7 @@
|
|||
* along with Mes. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <mlibc.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#error "POSIX not supported"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <mlibc.h>
|
||||
|
||||
char arena[300];
|
||||
|
|
|
@ -59,7 +59,7 @@ include make/mescc-guile.make
|
|||
|
||||
MAINTAINER-CLEAN+=mes.mes
|
||||
ifeq ($(wildcard mes.mes),)
|
||||
safe-MES_MAX_ARENA=$(MES_MAX_ARENA)
|
||||
safe-MES_MAX_ARENA:=$(MES_MAX_ARENA)
|
||||
MES_MAX_ARENA:=80000000
|
||||
TARGET:=mes.mes
|
||||
$(OUT)/mes.mes: module/mes/read-0-32.mo
|
||||
|
|
Loading…
Reference in a new issue