Compare commits
No commits in common. "master" and "release-5-6" have entirely different histories.
master
...
release-5-
74
.distr
74
.distr
@ -1,57 +1,21 @@
|
||||
README
|
||||
CHANGES
|
||||
Action
|
||||
Copyright
|
||||
pm
|
||||
pmfile
|
||||
config.pm
|
||||
|
||||
h
|
||||
modules/h
|
||||
|
||||
NEW
|
||||
README
|
||||
TODO
|
||||
TakeAction
|
||||
bin
|
||||
doc
|
||||
emtest
|
||||
etc
|
||||
fast
|
||||
fcc
|
||||
first
|
||||
util/data
|
||||
util/LLgen
|
||||
|
||||
modules/src/alloc
|
||||
modules/src/assert
|
||||
modules/src/system
|
||||
modules/src/string
|
||||
modules/src/read_em
|
||||
modules/src/em_code
|
||||
modules/src/em_mes
|
||||
modules/src/print
|
||||
modules/src/object
|
||||
modules/src/idf
|
||||
modules/src/input
|
||||
modules/src/flt_arith
|
||||
|
||||
util/amisc
|
||||
util/cmisc
|
||||
util/ack
|
||||
lib/descr/fe
|
||||
util/arch
|
||||
#util/cpp
|
||||
util/cgg
|
||||
util/ncgg
|
||||
util/misc
|
||||
util/opt
|
||||
util/ego
|
||||
util/topgen
|
||||
util/led
|
||||
|
||||
lang/cem
|
||||
lang/pc
|
||||
lang/m2
|
||||
#lang/occam
|
||||
#lang/basic
|
||||
|
||||
mach/proto
|
||||
mach/i80
|
||||
mach/i86
|
||||
mach/i386
|
||||
|
||||
plat/cpm
|
||||
plat/pc86
|
||||
plat/linux386
|
||||
|
||||
examples
|
||||
h
|
||||
include
|
||||
modules
|
||||
lang
|
||||
lib
|
||||
mach
|
||||
man
|
||||
util
|
||||
|
||||
8
Action
8
Action
@ -30,10 +30,10 @@ name "Modules"
|
||||
dir modules/src
|
||||
indir
|
||||
end
|
||||
! name "LL(1) Parser generator"
|
||||
! dir util/LLgen
|
||||
! action "make firstinstall && make clean"
|
||||
! end
|
||||
name "LL(1) Parser generator"
|
||||
dir util/LLgen
|
||||
action "make firstinstall && make clean"
|
||||
end
|
||||
name "C preprocessor"
|
||||
dir util/cpp
|
||||
end
|
||||
|
||||
35
CHANGES
35
CHANGES
@ -1,35 +0,0 @@
|
||||
# $Source$
|
||||
# $State$
|
||||
# $Revision$
|
||||
|
||||
6.0pre4
|
||||
|
||||
Fixed some minor bit-rotting issues that were preventing compilation on
|
||||
modern Linux systems.
|
||||
|
||||
6.0pre3
|
||||
|
||||
Added the cpm platform. Made some optimisations to the i80 code generator,
|
||||
including getting topgen up and running and adding some peephole optimiser
|
||||
rules. Fixed loads of bugs in ego so that it now works on platforms that
|
||||
support it (pc86 and linux386). Made the floating point work on platforms
|
||||
that support it (pc86 and linux386 again). Made stdint.h work. Lots and lots
|
||||
of bugfixes and tweaks everywhere.
|
||||
|
||||
6.0pre2
|
||||
|
||||
Much simplified the syscall interface by disabling libmon and instead
|
||||
calling the syscalls directly. Disabled the K&R C compiler and libc because
|
||||
it doesn't actually gain us anything and has a high maintenance load --- the
|
||||
ANSI C compiler works fine with K&R C. Adapted the rest of the system to
|
||||
build with the ANSI C compiler. Rewrote the pc86 syscall interface and added
|
||||
linux386 support, using the i386 code generator. Lots and lots of bugfixes
|
||||
and tweaks everywhere.
|
||||
|
||||
6.0pre1
|
||||
|
||||
First working version of the 6.0 release stream. Working frontends: both C
|
||||
compilers, Pascal, Modula-2, Basic and Occam. Working backends: i86. Working
|
||||
platforms: pc86, the very noddy testbed setup that produces floppy disk
|
||||
images.
|
||||
|
||||
260
README
260
README
@ -1,146 +1,148 @@
|
||||
THE AMSTERDAM COMPILER KIT V6.0pre4
|
||||
===================================
|
||||
# $Source$
|
||||
# $State$
|
||||
|
||||
© 1987-2005 Vrije Universiteit, Amsterdam
|
||||
2010-08-08
|
||||
Installing the ACK on a modern platform
|
||||
=======================================
|
||||
|
||||
This document provides some very quick and dirty instructions for installing
|
||||
the ACK on a modern platform. It is not intended as a substitute for the
|
||||
real instructions, which can be found in doc/install.pr.
|
||||
|
||||
INTRODUCTION
|
||||
============
|
||||
Let me repeat myself:
|
||||
|
||||
The Amsterdam Compiler Kit is a complete compiler toolchain consisting of
|
||||
front end compilers for a number of different languages, code generators,
|
||||
support libraries, and all the tools necessary to go from source code to
|
||||
executable on any of the platforms it supports.
|
||||
THE FULL INSTALLATION INSTRUCTIONS ARE IN doc/install.pr.
|
||||
|
||||
This is an early prerelease of the apocryphal version 6.0 release. Not a
|
||||
lot is supported, the build mechanism needs work, and a lot of things are
|
||||
probably broken. However, what's there should be sufficient to get things
|
||||
done and to evaluate how the full 6.0 release should work.
|
||||
The ACK is a very large and complex package and has received minimal
|
||||
maintenance for the best part of a decade. During that time, the Unix
|
||||
world has moved on, and many APIs have changed. It compiles cleanly on
|
||||
my, dtrg's, test machine, which is a Debian Ubuntu Linux system. Your
|
||||
mileage may vary.
|
||||
|
||||
All disclaimers now done, now on to the good stuff:
|
||||
|
||||
SUPPORT
|
||||
=======
|
||||
Building the ACK
|
||||
----------------
|
||||
|
||||
Languages:
|
||||
I'm assuming you're using Linux here, because that's what I use. If you
|
||||
don't use Linux, please let me know if you have any trouble and I'll update
|
||||
the instructions.
|
||||
|
||||
ANSI C, Pascal, Modula 2. K&R is supported via the ANSI C compiler.
|
||||
1. Configure the build.
|
||||
|
||||
Platforms:
|
||||
To do this, run the first/first script. You will be asked several
|
||||
questions.
|
||||
|
||||
* What is the root of the ACK source tree?
|
||||
|
||||
This is the directory that you have unpacked the distribution into.
|
||||
For example, /home/dg/src/Ack-5.6.
|
||||
|
||||
* What is the root of the configuration tree?
|
||||
|
||||
This is the directory that the build process will use for temporary
|
||||
files. You'll only need this during the compilation process; it can
|
||||
be removed afterwards.
|
||||
For example, /tmp/ack-conf
|
||||
|
||||
* What is the root of the ACK binaries?
|
||||
|
||||
This is the ACK's installation path; where the binaries will live.
|
||||
This needs to be writable during the build process --- if you want
|
||||
to install in /usr/local, you either have to make /usr/local
|
||||
writable or compile as root. Sorry!
|
||||
|
||||
* What is your system type?
|
||||
|
||||
Linux isn't on the list. Choose ANY.
|
||||
|
||||
* Is this the system you are running on?
|
||||
|
||||
Yes.
|
||||
|
||||
* Are you satisfied?
|
||||
|
||||
Yes.
|
||||
|
||||
* What default machine do you wish to compile for?
|
||||
|
||||
The ACK wants to know what architecture to target if you don't manually
|
||||
specify an architecture. Unfortunately, it can't generate runnable
|
||||
binaries for Linux or any other modern system (except possible Solaris
|
||||
on Sparc). I'd recommend you choose em44. This will produce portable
|
||||
binaries using the ACK's intermediate format, which you can run using
|
||||
the int interpreter.
|
||||
|
||||
* What kind of Unix are you running?
|
||||
|
||||
Linux is a mixture, but I pick SYS_5 and it works.
|
||||
|
||||
* Do you wish to limit the installation?
|
||||
|
||||
No. If you pick Yes, the script will ask detailed questions about
|
||||
exactly what you want to build. Modern systems are fast enough that
|
||||
we may as well build everything.
|
||||
|
||||
* Which system call library do you wish to use on the VAX?
|
||||
|
||||
I don't have a VAX; the only person I know who has one uses it to vacuum
|
||||
his carpets. I pick libsysV_2 with no ill effects.
|
||||
|
||||
If the configuration script is happy, it will generate a script called
|
||||
INSTALL.
|
||||
|
||||
2. Do the compilation.
|
||||
|
||||
pc86 produces bootable floppy disk images for 8086 PCs
|
||||
linux386 produces ELF executables for PC Linux systems
|
||||
cpm produces i80 CP/M .COM files
|
||||
The configuration script will recommend a command line. Execute this. On
|
||||
modern systems, the compilation doesn't take long.
|
||||
|
||||
Check the output of the configuration script for "Failed" lines. On my
|
||||
system there are two:
|
||||
|
||||
$ grep Failed INSTALL.out
|
||||
Failed for Intel 8080 download programs, see dl/Out
|
||||
Failed for Intel 8080 support
|
||||
|
||||
You can ignore these. They aren't important.
|
||||
|
||||
3. Use the ACK.
|
||||
|
||||
Ensure that the ACK's binary directory is on your path; this is /bin in
|
||||
the directory you specified during the configuration process. In my
|
||||
example, this is /usr/local/bin. The /man subdirectory should go on your
|
||||
manpath.
|
||||
|
||||
INSTALLATION
|
||||
============
|
||||
|
||||
The version 6.0 build mechanism has been completely rewritten and is based
|
||||
around the Prime Mover build tool (see http://primemover.sf.net for more
|
||||
information). Installation ought to be fairly straightforward.
|
||||
|
||||
Requirements:
|
||||
|
||||
- an ANSI C compiler. Currently, I'm afraid, it's hard-coded to use gcc.
|
||||
To change, try changing the variable definitions in first/c.pm. This also
|
||||
needs to be available as 'cc' from the shell.
|
||||
|
||||
- about 20MB free in /tmp (or some other temporary directory).
|
||||
|
||||
- about 6MB in the target directory.
|
||||
|
||||
Instructions:
|
||||
|
||||
- edit config.pm. There's a small section at the top containing some editable
|
||||
variables. Probably the only one you may want to edit is PREFIX, which
|
||||
changes where the ACK installs to.
|
||||
|
||||
- Run:
|
||||
|
||||
./pm configure
|
||||
|
||||
...from the command line. This will write out a configuration file.
|
||||
|
||||
- Run:
|
||||
|
||||
./pm
|
||||
|
||||
...from the command line. This will actually do the build. This takes
|
||||
about two minutes on my 1.6GHz Athlon Linux machine and about 30 on my
|
||||
166MHz Pentium OpenBSD machine.
|
||||
|
||||
- Run:
|
||||
|
||||
./pm install
|
||||
|
||||
...from the command line (possibly with sudo). This will install the built
|
||||
ACK into whatever directory you nominated in PREFIX.
|
||||
|
||||
The ACK should now be ready to use.
|
||||
|
||||
|
||||
USAGE
|
||||
=====
|
||||
|
||||
Currently I haven't sorted out all the documentation --- it's supplied in the
|
||||
distribution, but not all of it gets installed yet --- so here is a quickstart
|
||||
guide.
|
||||
|
||||
The main command to use is 'ack'. This invokes the compiler and the linker.
|
||||
Some useful options include:
|
||||
|
||||
-m<platform> build for the specified platform
|
||||
-o <file> specifies the output file
|
||||
-c produce a .o file
|
||||
-c.s produce a .s assembly file
|
||||
-O enable optimisation
|
||||
-ansi compile ANSI C (when using the C compiler)
|
||||
<file> build file
|
||||
|
||||
ack figures out which language to use from the file extension:
|
||||
|
||||
.c C (ANSI or K&R)
|
||||
.b Basic
|
||||
.mod Modula-2
|
||||
.ocm Occam 1
|
||||
.p Pascal
|
||||
.o object files
|
||||
.s assembly files
|
||||
|
||||
For further information, see the man page (which actually does get
|
||||
installed, but is rather out of date).
|
||||
|
||||
There are some (known working) example programs in the 'examples' directory.
|
||||
A sample command line is:
|
||||
|
||||
ack -mlinux386 -O examples/paranoia.c
|
||||
|
||||
|
||||
GOTCHAS
|
||||
=======
|
||||
To test your path, do: ack
|
||||
|
||||
This should return silently.
|
||||
|
||||
To test your manpath, do: man ack
|
||||
|
||||
This will produce the documentation for the main compiler driver.
|
||||
|
||||
If this works, you can remove the conf tree (/tmp/ack-conf in my example).
|
||||
|
||||
Gotchas
|
||||
-------
|
||||
|
||||
There are some things you should be aware of.
|
||||
|
||||
- Look at plat/<PLATFORMNAME>/README for information about the two supported
|
||||
platforms.
|
||||
* The ACK's archiver tool is called 'arch'. This conflicts on Linux platforms
|
||||
with a utility that displays the current architecture. If your compilation
|
||||
occasionally fails obscurely and displays something like 'i686', you are
|
||||
running afoul of this. As a workaround, rearrange your path so the ACK's
|
||||
bin directory comes first --- but do be aware that some Linux system
|
||||
tools may stop working.
|
||||
|
||||
- The library support is fairly limited; for C, it's at roughly the ANSI C
|
||||
level, and for the other languages it's similar.
|
||||
* By default, the ack tool will compile K&R C. Practically all C source these
|
||||
days is ANSI C --- use the -ansi switch to enable ANSI mode. No, the ACK is
|
||||
not C99 compatible.
|
||||
|
||||
- When compiling languages other than C, the ACK will usually look at the
|
||||
first character of the file. If it's a #, then the file will be run through
|
||||
the C preprocessor anyway.
|
||||
|
||||
- BSD systems may need to up the number of file descriptors (e.g.
|
||||
'ulimit -n 200') before the ACK will compile.
|
||||
* Not all combinations of optimisation and architectures work. This is
|
||||
perfectly normal, but the combinations are not well documented. Everything
|
||||
supports -O.
|
||||
|
||||
- The ACK uses its own .o format. You won't be able to mix the ACK's object
|
||||
files and another compiler's.
|
||||
|
||||
|
||||
DISCLAIMER
|
||||
==========
|
||||
Disclaimer
|
||||
----------
|
||||
|
||||
The ACK is mature, well-tested software, but the environment in which it was
|
||||
developed for and tested under is rather different from that available on
|
||||
@ -163,8 +165,10 @@ Please enjoy.
|
||||
|
||||
David Given (dtrg on Sourceforge)
|
||||
dg@cowlark.com
|
||||
2010-08-08
|
||||
2005-06-24, 23:53
|
||||
|
||||
# $Source$
|
||||
# $State$
|
||||
# $Revision$
|
||||
# Revision history
|
||||
# $Log$
|
||||
# Revision 2.2 2005-06-24 23:20:41 dtrg
|
||||
# Added some new readmes at the top level.
|
||||
#
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
case $# in
|
||||
0) PAR='make install && make clean' ; CMD=Action ;;
|
||||
1) PAR="$1" ; CMD=Action ;;
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
#!/bin/sh
|
||||
: '$Id$'
|
||||
|
||||
: Compile and make dependencies. First argument is the file on which the
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
#!/bin/sh
|
||||
: '$Id$'
|
||||
|
||||
: Compile and make dependencies. First argument is the file on which the
|
||||
@ -17,5 +16,5 @@ do
|
||||
;;
|
||||
esac
|
||||
done
|
||||
$UTIL_HOME/lib.bin/cpp -d -m $cpp_args > $n 2>/dev/null
|
||||
$UTIL_HOME/lib.bin/cpp -d -m $cpp_args > $n
|
||||
exec $CC $*
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
#!/bin/sh
|
||||
: '$Id$'
|
||||
|
||||
: Compile and make dependencies. First argument is the file on which the
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
#!/bin/sh
|
||||
: '$Id$'
|
||||
|
||||
: Produce dependencies for all argument files
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
#!/bin/sh
|
||||
: '$Id$'
|
||||
|
||||
: Resolve name clashes in the files on the argument list. If these
|
||||
|
||||
1
bin/em.pascal
Executable file
1
bin/em.pascal
Executable file
@ -0,0 +1 @@
|
||||
exec /usr/em/doc/em/int/em /usr/em/doc/em/int/tables ${1-e.out} core
|
||||
@ -1,4 +1,3 @@
|
||||
#!/bin/sh
|
||||
: '$Id$'
|
||||
|
||||
: Create a lint library file. The name of the library file is constructed
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
#!/bin/sh
|
||||
: '$Id$'
|
||||
|
||||
: Create a lint library file. The name of the library file is constructed
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
num=`expr $1 : '.*\.\([1-8]\)'`
|
||||
|
||||
if [ -d $2/man ] ; then : ; else mkdir $2/man ; fi
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
#!/bin/sh
|
||||
: $Id$
|
||||
|
||||
: remove dependencies from a makefile, write result on standard output.
|
||||
|
||||
71
config.pm
71
config.pm
@ -1,71 +0,0 @@
|
||||
-- ======================================================================= --
|
||||
-- ACK CONFIGURATION --
|
||||
-- (Edit this before building) --
|
||||
-- ======================================================================= --
|
||||
|
||||
-- What platform to build for by default?
|
||||
|
||||
DEFAULT_PLATFORM = "pc86"
|
||||
|
||||
-- Where should the ACK put its temporary files?
|
||||
|
||||
ACK_TEMP_DIR = "/tmp"
|
||||
|
||||
-- Where is the ACK going to be installed, eventually?
|
||||
|
||||
PREFIX = "/usr/local"
|
||||
|
||||
-- ======================================================================= --
|
||||
-- BROKEN ACK CONFIGURATION --
|
||||
-- (Currently not editable) --
|
||||
-- ======================================================================= --
|
||||
|
||||
-- FIXME: the following two variables must be set to their Minix variants
|
||||
-- due to hard-coded references in the descr files.
|
||||
|
||||
-- Name of the platform-independent library directory; 'share' on modern
|
||||
-- systems, 'lib' on Minix-like systems.
|
||||
|
||||
PLATIND = "lib"
|
||||
|
||||
-- Name of the platform-dependent library directory; 'lib' on modern
|
||||
-- systems, 'lib.bin' on Minix-like systems.
|
||||
|
||||
PLATDEP = "lib.bin"
|
||||
|
||||
-- ======================================================================= --
|
||||
-- BUILD SYSTEM CONFIGURATION --
|
||||
-- (Not user servicable) --
|
||||
-- ======================================================================= --
|
||||
|
||||
-- Absolute path to the ACK source directory.
|
||||
|
||||
ROOTDIR = posix.getcwd().."/"
|
||||
|
||||
-- Temporary directory used during the build process.
|
||||
|
||||
TEMPDIR = "/tmp/ack-temp/"
|
||||
|
||||
-- Directory in which dynamically generated header files will go during
|
||||
-- the build process.
|
||||
|
||||
HEADERDIR = TEMPDIR.."headers/"
|
||||
|
||||
-- Directory in which tools used by the build process but which not actually
|
||||
-- deployed with the ACK will go.
|
||||
|
||||
TOOLDIR = TEMPDIR.."tools/"
|
||||
|
||||
-- Directory in which the libraries used to build the ACK tools but which are
|
||||
-- not actually deployed with the ACK will go.
|
||||
|
||||
LIBDIR = TEMPDIR.."lib/"
|
||||
|
||||
-- Staging area where the installation will be built before actually copying
|
||||
-- it.
|
||||
|
||||
BINDIR = TEMPDIR.."staging/"
|
||||
|
||||
-- Directory that the pm cache goes in.
|
||||
|
||||
pm.intermediate_cache_dir = TEMPDIR.."pmcache/"
|
||||
3
distr/Action
Normal file
3
distr/Action
Normal file
@ -0,0 +1,3 @@
|
||||
name "EM tables"
|
||||
dir etc
|
||||
end
|
||||
16
distr/Action1
Normal file
16
distr/Action1
Normal file
@ -0,0 +1,16 @@
|
||||
name "m68k2/cg bootstrap files"
|
||||
dir mach/m68k2/cg
|
||||
action "make EMHOME=/proj/em/Work distr"
|
||||
end
|
||||
name "vax4/cg bootstrap files"
|
||||
dir mach/vax4/cg
|
||||
action "make EMHOME=/proj/em/Work distr"
|
||||
end
|
||||
name "m68020/ncg bootstrap files"
|
||||
dir mach/m68020/ncg
|
||||
action "make EMHOME=/proj/em/Work distr"
|
||||
end
|
||||
name "m68k4/cg bootstrap files"
|
||||
dir mach/m68k4/cg
|
||||
action "make EMHOME=/proj/em/Work distr"
|
||||
end
|
||||
@ -1,5 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
: ${CDIR=.}
|
||||
${DF-:} $CDIR .distr
|
||||
if test ! -r $DESTDIR/$CDIR/.distr
|
||||
|
||||
26
distr/f.attf
Normal file
26
distr/f.attf
Normal file
@ -0,0 +1,26 @@
|
||||
-- ./doc/install.pr no RCS file
|
||||
-- ./h/em_mnem.h no RCS file
|
||||
-- ./h/em_pseu.h no RCS file
|
||||
-- ./h/em_spec.h no RCS file
|
||||
-- ./lang/basic/src/y.tab.c no RCS file
|
||||
-- ./lang/basic/src/y.tab.h no RCS file
|
||||
-- ./lang/pc/pem/pem22.m no RCS file
|
||||
-- ./lang/pc/pem/pem24.m no RCS file
|
||||
-- ./lang/pc/pem/pem44.m no RCS file
|
||||
-- ./lib/LLgen/incl no RCS file
|
||||
-- ./lib/LLgen/rec no RCS file
|
||||
-- ./mach/m68k2/cg/tables1.c no RCS file
|
||||
-- ./mach/m68k2/cg/tables1.h no RCS file
|
||||
-- ./mach/m68020/ncg/tables1.c no RCS file
|
||||
-- ./mach/m68020/ncg/tables1.h no RCS file
|
||||
-- ./mach/vax4/cg/tables1.c no RCS file
|
||||
-- ./mach/vax4/cg/tables1.h no RCS file
|
||||
-- ./util/LLgen/src/parser no RCS file
|
||||
-- ./util/LLgen/src/LLgen.c no RCS file
|
||||
-- ./util/LLgen/src/Lpars.c no RCS file
|
||||
-- ./util/LLgen/src/Lpars.h no RCS file
|
||||
-- ./util/LLgen/src/tokens.c no RCS file
|
||||
-- ./util/data/em_flag.c no RCS file
|
||||
-- ./util/data/em_mnem.c no RCS file
|
||||
-- ./util/data/em_pseu.c no RCS file
|
||||
-- ./util/ego/share/pop_push.h no RCS file
|
||||
@ -1,4 +1,3 @@
|
||||
#!/bin/sh
|
||||
: Utility to make a tree of symbolic links to source tree.
|
||||
: Mount the source tree read-only, use this script, and then try installation.
|
||||
case $# in
|
||||
|
||||
80
distr/mkdist
80
distr/mkdist
@ -8,7 +8,7 @@ destdir=
|
||||
srcdir=`pwd`
|
||||
arch=/usr/local/bin/arch
|
||||
delete=no
|
||||
copy="ln"
|
||||
copy=ln
|
||||
|
||||
# --- Options parsing -------------------------------------------------------
|
||||
|
||||
@ -29,11 +29,7 @@ while [ "$1" != "" ]; do
|
||||
;;
|
||||
|
||||
-c|--copy)
|
||||
copy="cp -Rp"
|
||||
;;
|
||||
|
||||
-S|--symlink)
|
||||
copy="ln -s"
|
||||
copy="cp -dp"
|
||||
;;
|
||||
|
||||
-a|--arch)
|
||||
@ -48,7 +44,6 @@ while [ "$1" != "" ]; do
|
||||
echo " -d --destdir <path> The directory to create the distribution in."
|
||||
echo " -x --delete Erase the destination directory first."
|
||||
echo " -c --copy Make physical copies of the files. (default: hardlink)"
|
||||
echo " -S --symlink Make symbolic links instead of copying or hardlinking."
|
||||
echo " -a --arch <path> Where the ACK 'arch' tool is."
|
||||
echo " -h --help Display this message."
|
||||
exit 0
|
||||
@ -61,7 +56,7 @@ while [ "$1" != "" ]; do
|
||||
shift
|
||||
done
|
||||
|
||||
if [ "$destdir" = "" ]; then
|
||||
if [ "$destdir" == "" ]; then
|
||||
echo "You must specify a destination directory. (Try --help for help.)"
|
||||
exit 1
|
||||
fi
|
||||
@ -84,7 +79,6 @@ process_dir() {
|
||||
|
||||
path=$1
|
||||
cd $path
|
||||
echo $PWD
|
||||
|
||||
# Look for a LIST file and cache the first line.
|
||||
|
||||
@ -94,30 +88,35 @@ process_dir() {
|
||||
fi
|
||||
|
||||
for i in `cat $path/.distr`; do
|
||||
case "$i" in
|
||||
\#*) # Comment. Do nothing.
|
||||
;;
|
||||
|
||||
*)
|
||||
if [ -d $i ]; then
|
||||
# This is a directory. Recurse into it.
|
||||
|
||||
( process_dir $path/$i )
|
||||
elif [ -f $i ]; then
|
||||
# This is a file.
|
||||
|
||||
addfile $path/$i
|
||||
elif [ "$i" = "$archivename" ]; then
|
||||
# Build the named archive.
|
||||
if [ -d $i ]; then
|
||||
# This is a directory. Recurse into it.
|
||||
|
||||
$arch cDr `cat LIST`
|
||||
addfile $path/$archivename
|
||||
else
|
||||
echo "Don't know what to do with $i, listed in $PWD/.distr."
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
( process_dir $path/$i )
|
||||
elif [ -f $i ]; then
|
||||
# This is a file.
|
||||
|
||||
addfile $path/$i
|
||||
elif [ "$i" = "$archivename" ]; then
|
||||
# Build the named archive.
|
||||
|
||||
$arch cDr `cat LIST`
|
||||
addfile $path/$archivename
|
||||
else
|
||||
(
|
||||
PATH=$PATH:.
|
||||
export PATH
|
||||
make distr || make $i || (
|
||||
echo "Don't know what to do with $i, listed in $1/.distr."
|
||||
exit 1
|
||||
)
|
||||
|
||||
if [ ! -f "$path/$i" ]; then
|
||||
echo "Make failed for $i, listed in $path/.distr"
|
||||
exit 1
|
||||
fi
|
||||
addfile $path/$i
|
||||
)
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@ -131,7 +130,7 @@ if !(strings $arch | grep archiver > /dev/null); then
|
||||
echo "architecture.)"
|
||||
echo ""
|
||||
echo "Press RETURN to go ahead anyway, or CTRL+C to abort."
|
||||
read ignored
|
||||
read
|
||||
fi
|
||||
|
||||
# Actually do the work.
|
||||
@ -141,7 +140,7 @@ echo " into destination tree: $destdir"
|
||||
echo ""
|
||||
|
||||
if [ -e $destdir ]; then
|
||||
if [ "$delete" = "yes" ]; then
|
||||
if [ "$delete" == "yes" ]; then
|
||||
echo "Press RETURN to erase $destdir and its contents, or CTRL+C to abort."
|
||||
read
|
||||
echo "Erasing..."
|
||||
@ -159,18 +158,7 @@ echo "Done."
|
||||
|
||||
# Revision history
|
||||
# $Log$
|
||||
# Revision 1.5 2007-04-24 19:48:41 dtrg
|
||||
# Removed bashish.
|
||||
#
|
||||
# Revision 1.4 2007/02/25 20:56:41 dtrg
|
||||
# Performed major renovations to make the script work on OpenBSD.
|
||||
#
|
||||
# Revision 1.3 2007/02/24 02:05:56 dtrg
|
||||
# Removed some bashish; added comment support; removed the make
|
||||
# distr functionality, as nothing was using it any more and it was
|
||||
# causing problems.
|
||||
#
|
||||
# Revision 1.2 2005/06/24 23:19:23 dtrg
|
||||
# Revision 1.2 2005-06-24 23:19:23 dtrg
|
||||
# Added new mkdist tool.
|
||||
#
|
||||
# Revision 1.1 2005/06/24 22:13:57 dtrg
|
||||
|
||||
@ -16,6 +16,7 @@ regadd.doc
|
||||
toolkit.doc
|
||||
v7bugs.doc
|
||||
val.doc
|
||||
LLgen
|
||||
6500.doc
|
||||
i80.doc
|
||||
z80.doc
|
||||
|
||||
6
doc/ceg/Makefile
Normal file
6
doc/ceg/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
PIC=pic
|
||||
TBL=tbl
|
||||
REFER=refer
|
||||
|
||||
../ceg.doc: ceg.tr ceg.ref
|
||||
$(PIC) ceg.tr | $(REFER) -e -p ceg.ref | $(TBL) > $@
|
||||
284
doc/ceg/proposal.tr
Normal file
284
doc/ceg/proposal.tr
Normal file
@ -0,0 +1,284 @@
|
||||
.TL
|
||||
|
||||
Code Expander
|
||||
.br
|
||||
(proposal)
|
||||
|
||||
.SH
|
||||
Introduction
|
||||
.LP
|
||||
The \fBcode expander\fR, \fBce\fR, is a program that translates EM-code to
|
||||
objectcode. The main goal is to translate very fast. \fBce\fR is an instance
|
||||
of the EM_CODE(3L)-interface. During execution of \fBce\fR, \fBce\fR will build
|
||||
in core a machine independent objectfile ( NEW A.OUT(5L)). With \fBcv\fR or
|
||||
with routines supplied by the user the machine independent objectcode will
|
||||
be converted to a machine dependent object code. \fBce\fR needs
|
||||
information about the targetmachine (e.g. the opcode's). We divide the
|
||||
information into two parts:
|
||||
.IP
|
||||
- The description in assembly instructions of EM-code instructions.
|
||||
.IP
|
||||
- The description in objectcode of assembly instructions.
|
||||
.LP
|
||||
With these two tables we can make a \fBcode expander generator\fR which
|
||||
generates a \fBce\fR. It is possible to put the information in one table
|
||||
but that will probably introduce (propable) more bugs in the table. So we
|
||||
divide and conquer. With this approach it is also possible to generate
|
||||
assembly code ( rather yhan objectcode), wich is useful for debugging.
|
||||
There is of course a link between the two tables, the link
|
||||
consist of a restriction on the assembly format. Every assembly
|
||||
instruction must have the following format:
|
||||
.sp
|
||||
INSTR ::= LABEL : MNEMONIC [ OPERAND ( "," OPERAND)* ]
|
||||
.sp
|
||||
.LP
|
||||
\fBCeg\fR uses the following algorithm:
|
||||
.IP \0\0a)
|
||||
The assembly table will be converted to a (C-)routine assemble().
|
||||
assemble() gets as argument a string, the assembler instruction,
|
||||
and can use the MNEMONIC to execute the corresponding action in the
|
||||
assembly table.
|
||||
.IP \0\0b)
|
||||
The routine assemble() can now be used to convert the EM-code table to
|
||||
a set of C-routines, wich together form an instance of the
|
||||
EM_CODE(3L).
|
||||
.SH
|
||||
The EM-instruction table
|
||||
.LP
|
||||
We use the following grammar:
|
||||
.sp
|
||||
.TS
|
||||
center box ;
|
||||
l.
|
||||
TABLE ::= (ROW)*
|
||||
ROW ::= C_instr ( SPECIAL | SIMPLE)
|
||||
SPECIAL ::= ( CONDITION SIMPLE)+ 'default' SIMPLE
|
||||
SIMPLE ::= '==>' ACTIONLIST | '::=' ACTIONLIST
|
||||
ACTIONLIST ::= [ ACTION ( ';' ACTION)* ] '.'
|
||||
ACTION ::= function-call | assembly-instruction
|
||||
.TE
|
||||
.LP
|
||||
An example for the 8086:
|
||||
.LP
|
||||
.DS
|
||||
C_lxl
|
||||
$arg1 == 0 ==> "push bp".
|
||||
$arg1 == 1 ==> "push EM_BSIZE(bp)".
|
||||
default ==> "mov cx, $arg1";
|
||||
"mov si, bp";
|
||||
"1: mov si, EM_BSIZE(si);
|
||||
"loop 1b"
|
||||
"push si".
|
||||
.DE
|
||||
.sp
|
||||
Some remarks:
|
||||
.sp
|
||||
* The C_instr is a function indentifier in the EM_CODE(3L)-interface.
|
||||
.LP
|
||||
* CONDITION is a "boolean" C-expression.
|
||||
.LP
|
||||
* The arguments of an EM-instruction can be used in CONDITION and in assembly
|
||||
instructions. They are referred by $arg\fIi\fR. \fBceg\fR modifies the
|
||||
arguments as follows:
|
||||
.IP \0\0-
|
||||
For local variables at positive offsets it increases this offset by EM_BSIZE
|
||||
.IP \0\0-
|
||||
It makes names en labels unique. The user must supply the formats (see mach.h).
|
||||
.LP
|
||||
* function-call is allowed to implement e.g. push/pop optimization.
|
||||
For example:
|
||||
.LP
|
||||
.DS
|
||||
C_adi
|
||||
$arg1 == 2 ==> combine( "pop ax");
|
||||
combine( "pop bx");
|
||||
"add ax, bx";
|
||||
save( "push ax").
|
||||
default ==> arg_error( "C_adi", $arg1).
|
||||
.DE
|
||||
.LP
|
||||
* The C-functions called in the EM-instructions table have to use the routine
|
||||
assemble()/gen?(). "assembler-instr" is in fact assemble( "assembler-instr").
|
||||
.LP
|
||||
* \fBceg\fR takes care not only about the conversions of arguments but also
|
||||
about
|
||||
changes between segments. There are situation when one doesn't want
|
||||
conversion of arguments. This can be done by using ::= in stead of ==>.
|
||||
This is usefull when two C_instr are equivalent. For example:
|
||||
.IP
|
||||
C_slu ::= C_sli( $arg1)
|
||||
.LP
|
||||
* There are EM-CODE instructions wich are machine independent (e.g. C_open()).
|
||||
For these EM_CODE instructions \fBceg\fR will generate \fIdefault\fR-
|
||||
instructions. There is one exception: in the case of C_pro() the tablewriter
|
||||
has to supply a function prolog().
|
||||
.LP
|
||||
* Also the EM-pseudoinstructions C_bss_\fIcstp\fR(), C_hol_\fIcstp\fR(),
|
||||
C_con_\fIcstp\fR() and C_rom_\fIcstp\fR can be translated automaticly.
|
||||
\fBceg\fR only has to know how to interpretate string-constants:
|
||||
.DS
|
||||
\&..icon $arg2 == 1 ==> gen1( (char) atoi( $arg1))
|
||||
$arg2 == 2 ==> gen2( atoi( $arg1))
|
||||
$arg2 == 4 ==> gen4( atol( $arg1))
|
||||
\&..ucon $arg2 == 1 ==> gen1( (char) atoi( $arg1))
|
||||
$arg2 == 2 ==> gen2( atoi( $arg1))
|
||||
$arg2 == 4 ==> gen4( atol( $arg1))
|
||||
\&..fcon ::= not_implemented( "..fcon")
|
||||
.DE
|
||||
.LP
|
||||
* Still, life can be made easier for the tablewriter; For the routines wich
|
||||
he/she didn't implement \fBceg\fR will generate a default instruction wich
|
||||
generates an error-message. \fBceg\fR seems to generate :
|
||||
.IP
|
||||
C_xxx ::= not_implemented( "C_xxx")
|
||||
.SH
|
||||
The assembly table
|
||||
.LP
|
||||
How to map assembly on objectcode.
|
||||
.LP
|
||||
Each row in the table consists of two fields, one field for the assembly
|
||||
instruction, the other field for the corresponding objectcode. The tablewriter
|
||||
can use the following primitives to generate code for the machine
|
||||
instructions :
|
||||
.IP "\0\0gen1( b)\0\0:" 17
|
||||
generates one byte in de machine independent objectfile.
|
||||
.IP "\0\0gen2( w)\0\0:" 17
|
||||
generates one word ( = two bytes), the table writer can change the byte
|
||||
order by setting the flag BYTES_REVERSED.
|
||||
.IP "\0\0gen4( l)\0\0:" 17
|
||||
generates two words ( = four bytes), the table writer can change the word
|
||||
order by setting the flag WORDS_REVERSED.
|
||||
.IP "\0\0reloc( n, o, r)\0\0:" 17
|
||||
generates relocation information for a label ( = name + offset +
|
||||
relocationtype).
|
||||
.LP
|
||||
Besides these primitives the table writer may use his self written
|
||||
C-functions. This allows the table writer e.g. to write functions to set
|
||||
bitfields within a byte.
|
||||
.LP
|
||||
There are more or less two methods to encode the assembly instructions:
|
||||
.IP \0\0a)
|
||||
MNEMONIC and OPERAND('s) are encoded independently of each other. This can be
|
||||
done when the target machine has an orthogonal instruction set (e.g. pdp-11).
|
||||
.IP \0\0b)
|
||||
MNEMONIC and OPERAND('s) together determine the opcode. In this case the
|
||||
assembler often uses overloading: one MNEMONIC is used for several
|
||||
different machine-instructions. For example : (8086)
|
||||
.br
|
||||
mov ax, bx
|
||||
.br
|
||||
mov ax, variable
|
||||
.br
|
||||
These instructions have different opcodes.
|
||||
.LP
|
||||
As the transformation MNEMONIC-OPCODE is not one to
|
||||
one the table writer must be allowed to put restrictions on the operands.
|
||||
This can be done with type declarations. For example:
|
||||
.LP
|
||||
.DS
|
||||
mov dst:REG, src:MEM ==>
|
||||
gen1( 0x8b);
|
||||
modRM( op2.reg, op1);
|
||||
.DE
|
||||
.DS
|
||||
mov dst:REG, src:REG ==>
|
||||
gen1( 0x89);
|
||||
modRM( op2.reg, op1);
|
||||
.DE
|
||||
.LP
|
||||
modRM() is a function written by the tablewriter and is used to encode
|
||||
the operands. This frees the table writer of endless typing.
|
||||
.LP
|
||||
The table writer has to do the "typechecking" by himself. But typechecking
|
||||
is almost the same as operand decoding. So it's more efficient to do this
|
||||
in one function. We now have all the tools to describe the function
|
||||
assemble().
|
||||
.IP
|
||||
assemble() first calls the function
|
||||
decode_operand() ( by the table writer written), with two arguments: a
|
||||
string ( the operand) and a
|
||||
pointer to a struct. The struct is declared by the table writer and must
|
||||
consist of at least a field called type. ( the other fields in the struct can
|
||||
be used to remember information about the decoded operand.) Now assemble()
|
||||
fires a row wich is selected by mapping the MNEMONIC and the type of the
|
||||
operands.
|
||||
.br
|
||||
In the second field of a row there may be references to other
|
||||
fields in the struct (e.g. op2.reg in the example above).
|
||||
.LP
|
||||
We ignored one problem. It's possible when the operands are encoded, that
|
||||
not everything is known. For example $arg\fIi\fR arguments in the
|
||||
EM-instruction table get their value at runtime. This problem is solved by
|
||||
introducing a function eval(). eval() has a string as argument and returns
|
||||
an arith. The string consists of constants and/or $arg\fIi\fR's and the value
|
||||
returned by eval() is the value of the string. To encode the $arg\fIi\fR's
|
||||
in as few bytes as possible the table writer can use the statements %if,
|
||||
%else and %endif. They can be used in the same manner as #if, #else and
|
||||
#endif in C and result in a runtime test. An example :
|
||||
.LP
|
||||
.DS
|
||||
-- Some rows of the assembly table
|
||||
|
||||
mov dst:REG, src:DATA ==>
|
||||
%if sfit( eval( src), 8) /* does the immediate-data fit in 1 byte? */
|
||||
R53( 0x16 , op1.reg);
|
||||
gen1( eval( src));
|
||||
%else
|
||||
R53( 0x17 , op1.reg);
|
||||
gen2( eval( src));
|
||||
%endif
|
||||
.LD
|
||||
|
||||
mov dst:REG, src:REG ==>
|
||||
gen1( 0x8b);
|
||||
modRM( op1.reg, op2);
|
||||
|
||||
.DE
|
||||
.DS
|
||||
-- The corresponding part in the function assemble() :
|
||||
|
||||
case MNEM_mov :
|
||||
decode_operand( arg1, &op1);
|
||||
decode_operand( arg2, &op2);
|
||||
if ( REG( op1.type) && DATA( op2.type)) {
|
||||
printf( "if ( sfit( %s, 8)) {\\\\n", eval( src));
|
||||
R53( 0x16 , op1.reg);
|
||||
printf( "gen1( %s)\\\\n", eval( arg2));
|
||||
printf( "}\\\\nelse {\\\\n");
|
||||
R53( 0x17 , op1.reg);
|
||||
printf( "gen2( %s)\\\\n", eval( arg2));
|
||||
printf( "}\\\\n");
|
||||
}
|
||||
else if ( REG( op1.type) && REG( op2.type)) {
|
||||
gen1( 0x8b);
|
||||
modRM( op1.reg, op2);
|
||||
}
|
||||
|
||||
|
||||
.DE
|
||||
.DS
|
||||
-- Some rows of the right part of the EM-instruction table are translated
|
||||
-- in the following C-functions.
|
||||
|
||||
"mov ax, $arg1" ==>
|
||||
if ( sfit( w, 8)) { /* w is the actual argument of C_xxx( w) */
|
||||
gen1( 176); /* R53() */
|
||||
gen1( w);
|
||||
}
|
||||
else {
|
||||
gen1( 184);
|
||||
gen2( w);
|
||||
}
|
||||
.LD
|
||||
|
||||
"mov ax, bx" ==>
|
||||
gen1( 138);
|
||||
gen1( 99); /* modRM() */
|
||||
.DE
|
||||
.SH
|
||||
Restrictions
|
||||
.LP
|
||||
.IP \0\01)
|
||||
The EM-instructions C_exc() is not implemented.
|
||||
.IP \0\03)
|
||||
All messages are ignored.
|
||||
276
doc/ceg/prototype.tr
Normal file
276
doc/ceg/prototype.tr
Normal file
@ -0,0 +1,276 @@
|
||||
.TL
|
||||
A prototype Code expander
|
||||
.NH
|
||||
Introduction
|
||||
.PP
|
||||
A program to be compiled with ACK is first fed into the preprocessor.
|
||||
The output of the preprocessor goes into the appropiate front end,
|
||||
whose job it is to produce EM. The EM code generated is
|
||||
fed into the peephole optimizer, wich scans it with a window of few
|
||||
instructions, replacing certain inefficient code sequences by better
|
||||
ones. Following the peephole optimizer follows a backend wich produces
|
||||
good assembly code. The assembly code goes into the assembler and the objectcode
|
||||
then goes into the loader/linker, the final component in the pipeline.
|
||||
.PP
|
||||
For various applications this scheme is too slow. For example for testing
|
||||
programs; In this case the program has to be translated fast and the
|
||||
runtime of the objectcode may be slower. A solution is to build a code
|
||||
expander ( \fBce\fR) wich translates EM code to objectcode. Of course this
|
||||
has to
|
||||
be done automaticly by a code expander generator, but to get some feeling
|
||||
for the problem we started out to build prototypes.
|
||||
We built two types of ce's. One wich tranlated EM to assembly, one
|
||||
wich translated EM to objectcode.
|
||||
.NH
|
||||
EM to assembly
|
||||
.PP
|
||||
We made one for the 8086 and one for the vax4. These ce's are instances of the
|
||||
EM_CODE(3L)-interface and produce for a single EM instruction a set
|
||||
of assembly instruction wich are semantic equivalent.
|
||||
We implemented in the 8086-ce push/pop-optimalization.
|
||||
.NH
|
||||
EM to objectcode
|
||||
.PP
|
||||
Instead of producing assembly code we tried to produce vax4-objectcode.
|
||||
During execution of ce, ce builds in core a machine independent
|
||||
objectfile ( NEW A.OUT(5L)) and just before dumping the tables this
|
||||
objectfile is converted to a Berkly 4.2BSD a.out-file. We build two versions;
|
||||
One with static memory allocation and one with dynamic memory allocation.
|
||||
If the first one runs out of memory it will give an error message and stop,
|
||||
the second one will allocate more memory and proceed with producing
|
||||
objectcode.
|
||||
.PP
|
||||
The C-frontend calls the EM_CODE-interface. So after linking the frontend
|
||||
and the ce we have a pipeline in a program saving a lot of i/o.
|
||||
It is interesting to compare this C-compiler ( called fcemcom) with "cc -c".
|
||||
fcemcom1 (the dynamic variant of fcemcom) is tuned in such a way, that
|
||||
alloc() won't be called.
|
||||
.NH 2
|
||||
Compile time
|
||||
.PP
|
||||
fac.c is a small program that produces n! ( see below). foo.c is small program
|
||||
that loops a lot.
|
||||
.TS
|
||||
center, box, tab(:);
|
||||
c | c | c | c | c | c
|
||||
c | c | n | n | n | n.
|
||||
compiler : program : real : user : sys : object size
|
||||
=
|
||||
fcemcom : sort.c : 31.0 : 17.5 : 1.8 : 23824
|
||||
fcemcom1 : : 59.0 : 21.2 : 3.3 :
|
||||
cc -c : : 50.0 : 38.0 : 3.5 : 6788
|
||||
_
|
||||
fcemcom : ed.c : 37.0 : 23.6 : 2.3 : 41744
|
||||
fcemcom1 : : 1.16.0 : 28.3 : 4.6 :
|
||||
cc -c : : 1.19.0 : 54.8 : 4.3 : 11108
|
||||
_
|
||||
fcemcom : cp.c : 4.0 : 2.4 : 0.8 : 4652
|
||||
fcemcom1 : : 9.0 : 3.0 : 1.0 :
|
||||
cc -c : : 8.0 : 5.2 : 1.6 : 1048
|
||||
_
|
||||
fcemcom : uniq.c : 5.0 : 2.5 : 0.8 : 5568
|
||||
fcemcom1 : : 9.0 : 2.9 : 0.8 :
|
||||
cc -c : : 13.0 : 5.4 : 2.0 : 3008
|
||||
_
|
||||
fcemcom : btlgrep.c : 24.0 : 7.2 : 1.4 : 12968
|
||||
fcemcom1 : : 23.0 : 8.1 : 1.2 :
|
||||
cc -c : : 1.20.0 : 15.3 : 3.8 : 2392
|
||||
_
|
||||
fcemcom : fac.c : 1.0 : 0.1 : 0.5 : 216
|
||||
fecmcom1 : : 2.0 : 0.2 : 0.5 :
|
||||
cc -c : : 3.0 : 0.7 : 1.3 : 92
|
||||
_
|
||||
fcemcom : foo.c : 4.0 : 0.2 : 0.5 : 272
|
||||
fcemcom1 : : 11.0 : 0.3 : 0.5 :
|
||||
cc -c : : 7.0 : 0.8 : 1.6 : 108
|
||||
.TE
|
||||
.NH 2
|
||||
Run time
|
||||
.LP
|
||||
Is the runtime very bad?
|
||||
.TS
|
||||
tab(:), box, center;
|
||||
c | c | c | c | c
|
||||
c | c | n | n | n.
|
||||
compiler : program : real : user : system
|
||||
=
|
||||
fcem : sort.c : 22.0 : 17.5 : 1.5
|
||||
cc : : 5.0 : 2.4 : 1.1
|
||||
_
|
||||
fcem : btlgrep.c : 1.58.0 : 27.2 : 4.2
|
||||
cc : : 12.0 : 3.6 : 1.1
|
||||
_
|
||||
fcem : foo.c : 1.0 : 0.7 : 0.1
|
||||
cc : : 1.0 : 0.4 : 0.1
|
||||
_
|
||||
fcem : uniq.c : 2.0 : 0.5 : 0.3
|
||||
cc : : 1.0 : 0.1 : 0.2
|
||||
.TE
|
||||
.NH 2
|
||||
quality object code
|
||||
.LP
|
||||
The runtime is very bad so its interesting to have look at the code which is
|
||||
produced by fcemcom and by cc -c. I took a program which computes recursively
|
||||
n!.
|
||||
.DS
|
||||
long fac();
|
||||
|
||||
main()
|
||||
{
|
||||
int n;
|
||||
|
||||
scanf( "%D", &n);
|
||||
printf( "fac is %D\\\\n", fac( n));
|
||||
}
|
||||
|
||||
long fac( n)
|
||||
int n;
|
||||
{
|
||||
if ( n == 0)
|
||||
return( 1);
|
||||
else
|
||||
return( n * fac( n-1));
|
||||
}
|
||||
.DE
|
||||
.br
|
||||
.br
|
||||
.br
|
||||
.br
|
||||
.LP
|
||||
"cc -c fac.c" produces :
|
||||
.DS
|
||||
fac: tstl 4(ap)
|
||||
bnequ 7f
|
||||
movl $1, r0
|
||||
ret
|
||||
7f: subl3 $1, 4(ap), r0
|
||||
pushl r0
|
||||
call $1, fac
|
||||
movl r0, -4(fp)
|
||||
mull3 -4(fp), 4(ap), r0
|
||||
ret
|
||||
.DE
|
||||
.br
|
||||
.br
|
||||
.LP
|
||||
"fcem fac.c fac.o" produces :
|
||||
.DS
|
||||
_fac: 0
|
||||
42: jmp be
|
||||
48: pushl 4(ap)
|
||||
4e: pushl $0
|
||||
54: subl2 (sp)+,(sp)
|
||||
57: tstl (sp)+
|
||||
59: bnequ 61
|
||||
5b: jmp 67
|
||||
61: jmp 79
|
||||
67: pushl $1
|
||||
6d: jmp ba
|
||||
73: jmp b9
|
||||
79: pushl 4(ap)
|
||||
7f: pushl $1
|
||||
85: subl2 (sp)+,(sp)
|
||||
88: calls $0,_fac
|
||||
8f: addl2 $4,sp
|
||||
96: pushl r0
|
||||
98: pushl 4(ap)
|
||||
9e: pushl $4
|
||||
a4: pushl $4
|
||||
aa: jsb .cii
|
||||
b0: mull2 (sp)+,(sp)
|
||||
b3: jmp ba
|
||||
b9: ret
|
||||
ba: movl (sp)+,r0
|
||||
bd: ret
|
||||
be: jmp 48
|
||||
.DE
|
||||
.NH 1
|
||||
Conclusions
|
||||
.PP
|
||||
comparing "cc -c" with "fcemcom"
|
||||
.LP
|
||||
.TS
|
||||
center, box, tab(:);
|
||||
c | c s | c | c s
|
||||
^ | c s | ^ | c s
|
||||
^ | c | c | ^ | c | c
|
||||
l | n | n | n | n | n.
|
||||
program : compile time : object size : runtime
|
||||
:_::_
|
||||
: user : sys :: user : sys
|
||||
=
|
||||
sort.c : 0.47 : 0.5 : 3.5 : 7.3 : 1.4
|
||||
_
|
||||
ed.c : 0.46 : 0.5 : 3.8 : : :
|
||||
_
|
||||
cp.c : 0.46 : 0.5 : 4.4 : : :
|
||||
_
|
||||
uniq.c : 0.46 : 0.4 : 1.8 : : :
|
||||
_
|
||||
btlgrep.c : 0.47 : 0.3 : 5.4 : 7.5 : 3.8
|
||||
_
|
||||
fac.c : 0.14 : 0.4 : 2.3 : 1.8 : 1.0
|
||||
_
|
||||
foo.c : 0.25 : 0.3 : 2.5 : 5.0 : 1.5
|
||||
.TE
|
||||
.PP
|
||||
The results for fcemcom1 are almost identical; The only thing that changes
|
||||
is that fcemcom1 is 1.2 slower than fcemcom. ( compile time) This is due to
|
||||
to an another datastructure . In the static version we use huge array's for
|
||||
the text- and
|
||||
data-segment, the relocation information, the symboltable and stringarea.
|
||||
In the dynamic version we use linked lists, wich makes it expensive to get
|
||||
and to put a byte on a abritrary memory location. So it is probably better
|
||||
to use realloc(), because in the most cases there will be enough memory.
|
||||
.PP
|
||||
The quality of the objectcode is very bad. The reason is that the frontend
|
||||
generates bad code and expects the peephole-optimizer to improve the code.
|
||||
This is also one of the main reasons that the runtime is very bad.
|
||||
(e.g. the expensive "cii" with arguments 4 and 4 could be deleted.)
|
||||
So its seems a good
|
||||
idea to put a new peephole-optimizer between the frontend and the ce.
|
||||
.PP
|
||||
Using the peephole optimizer the ce would produce :
|
||||
.DS
|
||||
_fac: 0
|
||||
pushl 4(ap)
|
||||
tstl (sp)+
|
||||
beqlu 1f
|
||||
jmp 3f
|
||||
1 : pushl $1
|
||||
jmp 2f
|
||||
3 : pushl 4(ap)
|
||||
decl (sp)
|
||||
calls $0,_fac
|
||||
addl2 $4,sp
|
||||
pushl r0
|
||||
pushl 4(ap)
|
||||
mull2 (sp)+,(sp)
|
||||
movl (sp)+,r0
|
||||
2 : ret
|
||||
.DE
|
||||
.PP
|
||||
Bruce McKenzy already implemented it and made some improvements in the
|
||||
source code of the ce. The compile-time is two to two and a half times better
|
||||
and the
|
||||
size of the objectcode is two to three times bigger.(comparing with "cc -c")
|
||||
Still we could do better.
|
||||
.PP
|
||||
Using peephole- and push/pop-optimization ce could produce :
|
||||
.DS
|
||||
_fac: 0
|
||||
tstl 4(ap)
|
||||
beqlu 1f
|
||||
jmp 2f
|
||||
1 : pushl $1
|
||||
jmp 3f
|
||||
2 : decl 4(ap)
|
||||
calls $0,_fac
|
||||
addl2 $4,sp
|
||||
mull3 4(ap), r0, -(sp)
|
||||
movl (sp)+, r0
|
||||
3 : ret
|
||||
.DE
|
||||
.PP
|
||||
prof doesn't cooperate, so no profile information.
|
||||
.PP
|
||||
323
doc/cref.doc
Normal file
323
doc/cref.doc
Normal file
@ -0,0 +1,323 @@
|
||||
.\" $Header$
|
||||
.nr ID 4
|
||||
.de hd
|
||||
'sp 2
|
||||
'tl ''-%-''
|
||||
'sp 3
|
||||
..
|
||||
.de fo
|
||||
'bp
|
||||
..
|
||||
.tr ~
|
||||
. TITLE
|
||||
.de TL
|
||||
.sp 15
|
||||
.ce
|
||||
\\fB\\$1\\fR
|
||||
..
|
||||
. AUTHOR
|
||||
.de AU
|
||||
.sp 15
|
||||
.ce
|
||||
by
|
||||
.sp 2
|
||||
.ce
|
||||
\\$1
|
||||
..
|
||||
. DATE
|
||||
.de DA
|
||||
.sp 3
|
||||
.ce
|
||||
( Dated \\$1 )
|
||||
..
|
||||
. INSTITUTE
|
||||
.de VU
|
||||
.sp 3
|
||||
.ce 4
|
||||
Wiskundig Seminarium
|
||||
Vrije Universteit
|
||||
De Boelelaan 1081
|
||||
Amsterdam
|
||||
..
|
||||
. PARAGRAPH
|
||||
.de PP
|
||||
.sp
|
||||
.ti +\n(ID
|
||||
..
|
||||
.nr CH 0 1
|
||||
. CHAPTER
|
||||
.de CH
|
||||
.nr SH 0 1
|
||||
.bp
|
||||
.in 0
|
||||
\\fB\\n+(CH.~\\$1\\fR
|
||||
.PP
|
||||
..
|
||||
. SUBCHAPTER
|
||||
.de SH
|
||||
.sp 3
|
||||
.in 0
|
||||
\\fB\\n(CH.\\n+(SH.~\\$1\\fR
|
||||
.PP
|
||||
..
|
||||
. INDENT START
|
||||
.de IS
|
||||
.sp
|
||||
.in +\n(ID
|
||||
..
|
||||
. INDENT END
|
||||
.de IE
|
||||
.in -\n(ID
|
||||
.sp
|
||||
..
|
||||
.de PT
|
||||
.ti -\n(ID
|
||||
.ta \n(ID
|
||||
.fc " @
|
||||
"\\$1@"\c
|
||||
.fc
|
||||
..
|
||||
. DOUBLE INDENT START
|
||||
.de DS
|
||||
.sp
|
||||
.in +\n(ID
|
||||
.ll -\n(ID
|
||||
..
|
||||
. DOUBLE INDENT END
|
||||
.de DE
|
||||
.ll +\n(ID
|
||||
.in -\n(ID
|
||||
.sp
|
||||
..
|
||||
. EQUATION START
|
||||
.de EQ
|
||||
.sp
|
||||
.nf
|
||||
..
|
||||
. EQUATION END
|
||||
.de EN
|
||||
.fi
|
||||
.sp
|
||||
..
|
||||
. ITEM
|
||||
.de IT
|
||||
.sp
|
||||
.in 0
|
||||
\\fB~\\$1\\fR
|
||||
.ti +5
|
||||
..
|
||||
.de CS
|
||||
.br
|
||||
~-~\\
|
||||
..
|
||||
.br
|
||||
.fi
|
||||
.TL "Ack-C reference manual"
|
||||
.AU "Ed Keizer"
|
||||
.DA "September 12, 1983"
|
||||
.VU
|
||||
.wh 0 hd
|
||||
.wh 60 fo
|
||||
.CH "Introduction"
|
||||
The C frontend included in the Amsterdam Compiler Kit
|
||||
translates UNIX-V7 C into compact EM code [1].
|
||||
The language accepted is described in [2] and [3].
|
||||
This document describes which implementation dependent choices were
|
||||
made in the Ack-C frontend and
|
||||
some restrictions and additions.
|
||||
.CH "The language"
|
||||
.PP
|
||||
Under the same heading as used in [2] we describe the
|
||||
properties of the Ack-C frontend.
|
||||
.IT "2.2 Identifiers"
|
||||
External identifiers are unique up to 7 characters and allow
|
||||
both upper and lower case.
|
||||
.IT "2.3 Keywords"
|
||||
The word \fBvoid\fP is also reserved as a keyword.
|
||||
.IT "2.4.3 Character constants"
|
||||
The ASCII-mapping is used when a character is converted to an
|
||||
integer.
|
||||
.IT "2.4.4 Floating constants"
|
||||
To prevent loss of precision the compiler does not perform
|
||||
floating point constant folding.
|
||||
.IT "2.6 Hardware characteristics"
|
||||
The size of objects of the several arithmetic types and
|
||||
pointers depend on the EM-implementation used.
|
||||
The ranges of the arithmetic types depend on the size used,
|
||||
the C-frontend assumes two's complement representation for the
|
||||
integral types.
|
||||
All sizes are multiples of bytes.
|
||||
The calling program \fIack\fP[4] passes information about the
|
||||
size of the types to the compiler proper.
|
||||
.br
|
||||
However, a few general remarks must be made:
|
||||
.sp 1
|
||||
.IS
|
||||
.PT (a)
|
||||
The size of pointers is a multiple of
|
||||
(or equal to) the size of an \fIint\fP.
|
||||
.PT (b)
|
||||
The following relations exist for the sizes of the types
|
||||
mentioned:
|
||||
.br
|
||||
.ti +5
|
||||
\fIchar<=short<=int<=long\fP
|
||||
.PT (c)
|
||||
Objects of type \fIchar\fP use one 8-bit byte of storage,
|
||||
although several bytes are allocated sometimes.
|
||||
.PT (d)
|
||||
All sizes are in multiples of bytes.
|
||||
.PT (e)
|
||||
Most EM implementations use 4 bytes for floats and 8 bytes
|
||||
for doubles, but exceptions to this rule occur.
|
||||
.IE
|
||||
.IT "4 What's in a name"
|
||||
The type \fIvoid\fP is added.
|
||||
Objects of type void do not exist.
|
||||
Functions declared as returning void, do not return a value at all.
|
||||
.IT "6.1 Characters and integers"
|
||||
Objects of type \fIchar\fP are unsigned and do not cause
|
||||
sign-extension when converted to \fIint\fP.
|
||||
The range of characters values is from 0 to 255.
|
||||
.IT "6.3 Floating and integral"
|
||||
Floating point numbers are truncated towards zero when
|
||||
converted to the integral types.
|
||||
.IT "6.4 Pointers and integers"
|
||||
When a \fIlong\fP is added to or subtracted from a pointer and
|
||||
longs are larger then pointers the \fIlong\fP is converted to an
|
||||
\fIint\fP before the operation is performed.
|
||||
.IT "7.2 Unary operators"
|
||||
It is allowed to cast any expression to the type \fIvoid\fP.
|
||||
.IT "8.2 Type specifiers"
|
||||
One type is added to the type-specifiers:
|
||||
.br
|
||||
.IS
|
||||
void
|
||||
.IE
|
||||
.IT "8.5 Structure and union declarations"
|
||||
The only type allowed for fields is \fIint\fP.
|
||||
Fields with exactly the size of \fIint\fP are signed,
|
||||
all other fields are unsigned.
|
||||
.br
|
||||
The size of any single structure must be less then 4096 bytes.
|
||||
.IT "8.6 Initialization"
|
||||
Initialization of structures containing bit fields is not
|
||||
allowed.
|
||||
There is one restriction when using an 'address expression' to initialize
|
||||
an integral variable.
|
||||
The integral variable must have the same size as a pointer.
|
||||
Conversions altering the size of the address expression are not allowed.
|
||||
.IT "9.10 Return statement"
|
||||
Return statements of the form:
|
||||
.IS
|
||||
return ;
|
||||
.IE
|
||||
are the only form of return statement allowed in a function of type
|
||||
function returning void.
|
||||
.IT "10.1 External function definitions"
|
||||
The total amount for storage used for parameters
|
||||
in any function must be less then 4096 bytes.
|
||||
The same holds for the total amount of storage occupied by the
|
||||
automatic variables declared inside any function.
|
||||
.sp
|
||||
Using formal parameters whose size is smaller the the size of an int
|
||||
is less efficient on several machines.
|
||||
At procedure entry these parameters are converted from integer to the
|
||||
declared type, because the compiler doesn't know where the least
|
||||
significant bytes are stored in the int.
|
||||
.IT "11.2 Scope of externals"
|
||||
Most C compilers are rather lax in enforcing the restriction
|
||||
that only one external definition without the keyword
|
||||
\fIextern\fP is allowed in a program.
|
||||
The Ack-C frontend is very strict in this.
|
||||
The only exception is that declarations of arrays with a
|
||||
missing first array bounds expression are regarded to have an
|
||||
explicit keyword \fIextern\fP.
|
||||
.IT "14.4 Explicit pointer conversions"
|
||||
Pointers may be larger the ints, thus assigning a pointer to an
|
||||
int and back will not always result in the same pointer.
|
||||
The process mentioned above works with integrals
|
||||
of the same size or larger as pointers in all EM implementations
|
||||
having such integrals.
|
||||
When converting pointers to an integral type or vice-versa,
|
||||
the pointers is seen as an unsigned int.
|
||||
.br
|
||||
EM guarantees that any object can be placed at a word boundary,
|
||||
this allows the C-programs to use \fIint\fP pointers
|
||||
as pointers to objects of any type not smaller than an \fIint\fP.
|
||||
.CH "Frontend options"
|
||||
The C-frontend has a few options, these are controlled
|
||||
by flags:
|
||||
.IS
|
||||
.PT -V
|
||||
This flag is followed by a sequence of letters each followed by
|
||||
positive integers. Each letter indicates a
|
||||
certain type, the integer following it specifies the size of
|
||||
objects of that type. One letter indicates the wordsize used.
|
||||
.IS
|
||||
.sp 1
|
||||
.TS
|
||||
center tab(:);
|
||||
l l16 l l.
|
||||
letter:type:letter:type
|
||||
|
||||
w:wordsize:i:int
|
||||
s:short:l:long
|
||||
f:float:d:double
|
||||
p:pointer::
|
||||
.TE
|
||||
.sp 1
|
||||
All existing implementations use an integer size equal to the
|
||||
wordsize.
|
||||
.IE
|
||||
The calling program \fIack\fP[4] provides the frontend with
|
||||
this flag, with values depending on the machine used.
|
||||
.sp 1
|
||||
.PT -l
|
||||
The frontend normally generates code to keep track of the line
|
||||
number and source file name at runtime for debugging purposes.
|
||||
Currently a pointer to a
|
||||
string containing the filename is stored at a fixed place in
|
||||
memory at each function
|
||||
entry and the line number at the start of every expression.
|
||||
At the return from a function these memory locations are not reset to
|
||||
the values they had before the call.
|
||||
Most library routines do not use this feature and thus do not
|
||||
ruin the current line number and filename when called.
|
||||
However, you are really unlucky when your program crashes due
|
||||
to a bug in such a library function, because the line number
|
||||
and filename do not indicate that something went wrong inside
|
||||
the library function.
|
||||
.br
|
||||
Providing the flag -l to the frontend tells it not to generate
|
||||
the code updating line number and file name.
|
||||
This is, for example, used when translating the stdio library.
|
||||
.br
|
||||
When the \fIack\fP[4] is called with the -L flag it provides
|
||||
the frontend with this flag.
|
||||
.sp 1
|
||||
.PT -Xp
|
||||
When this flag is present the frontend generates a call to
|
||||
the function \fBprocentry\fP at each function entry and a
|
||||
call to \fBprocexit\fP at each function exit.
|
||||
Both functions are provided with one parameter,
|
||||
a pointer to a string containing the function name.
|
||||
.br
|
||||
When \fIack\fP is called with the -p flag it provides the
|
||||
frontend with this flag.
|
||||
.IE
|
||||
.CH References
|
||||
.IS
|
||||
.PT [1]
|
||||
A.S. Tanenbaum, Hans van Staveren, Ed Keizer and Johan
|
||||
Stevenson \fIDescription of a machine architecture for use with
|
||||
block structured languages\fP Informatica report IR-81.
|
||||
.sp 1
|
||||
.PT [2]
|
||||
B.W. Kernighan and D.M. Ritchie, \fIThe C Programming
|
||||
language\fP, Prentice-Hall, 1978
|
||||
.PT [3]
|
||||
D.M. Ritchie, \fIC Reference Manual\fP
|
||||
.sp
|
||||
.PT [4]
|
||||
UNIX manual ack(I).
|
||||
55
doc/ego/Makefile
Normal file
55
doc/ego/Makefile
Normal file
@ -0,0 +1,55 @@
|
||||
REFS=-p refs.opt -p refs.stat -p refs.gen
|
||||
INTRO=intro/intro?
|
||||
OV=ov/ov?
|
||||
IC=ic/ic?
|
||||
CF=cf/cf?
|
||||
IL=il/il?
|
||||
SR=sr/sr?
|
||||
CS=cs/cs?
|
||||
SP=sp/sp?
|
||||
UD=ud/ud?
|
||||
LV=lv/lv?
|
||||
CJ=cj/cj?
|
||||
BO=bo/bo?
|
||||
RA=ra/ra?
|
||||
CA=ca/ca?
|
||||
EGO=$(INTRO) $(OV) $(IC) $(CF) $(IL) $(SR) $(CS) $(SP) $(CJ) $(BO) \
|
||||
$(UD) $(LV) $(RA) $(CA)
|
||||
REFER=refer
|
||||
TROFF=troff
|
||||
TBL=tbl
|
||||
TARGET=-Tlp
|
||||
|
||||
../ego.doc: refs.opt refs.stat refs.gen intro/head intro/tail $(EGO)
|
||||
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(EGO) intro/tail | $(TBL) > ../ego.doc
|
||||
|
||||
ego.f: refs.opt refs.stat refs.gen intro/head intro/tail $(EGO)
|
||||
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(EGO) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > ego.f
|
||||
intro.f: refs.opt refs.stat refs.gen intro/head intro/tail $(INTRO)
|
||||
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(INTRO) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > intro.f
|
||||
ov.f: refs.opt refs.stat refs.gen intro/head intro/tail $(OV)
|
||||
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(OV) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > ov.f
|
||||
ic.f: refs.opt refs.stat refs.gen intro/head intro/tail $(IC)
|
||||
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(IC) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > ic.f
|
||||
cf.f: refs.opt refs.stat refs.gen intro/head intro/tail $(CF)
|
||||
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(CF) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > cf.f
|
||||
il.f: refs.opt refs.stat refs.gen intro/head intro/tail $(IL)
|
||||
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(IL) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > il.f
|
||||
sr.f: refs.opt refs.stat refs.gen intro/head intro/tail $(SR)
|
||||
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(SR) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > sr.f
|
||||
cs.f: refs.opt refs.stat refs.gen intro/head intro/tail $(CS)
|
||||
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(CS) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > cs.f
|
||||
sp.f: refs.opt refs.stat refs.gen intro/head intro/tail $(SP)
|
||||
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(SP) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > sp.f
|
||||
cj.f: refs.opt refs.stat refs.gen intro/head intro/tail $(CJ)
|
||||
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(CJ) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > cj.f
|
||||
bo.f: refs.opt refs.stat refs.gen intro/head intro/tail $(BO)
|
||||
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(BO) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > bo.f
|
||||
ud.f: refs.opt refs.stat refs.gen intro/head intro/tail $(UD)
|
||||
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(UD) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > ud.f
|
||||
lv.f: refs.opt refs.stat refs.gen intro/head intro/tail $(LV)
|
||||
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(LV) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > lv.f
|
||||
ra.f: refs.opt refs.stat refs.gen intro/head intro/tail $(RA)
|
||||
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(RA) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > ra.f
|
||||
ca.f: refs.opt refs.stat refs.gen intro/head intro/tail $(CA)
|
||||
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(CA) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > ca.f
|
||||
37
doc/em/Makefile
Normal file
37
doc/em/Makefile
Normal file
@ -0,0 +1,37 @@
|
||||
HOME=../..
|
||||
|
||||
TBL=tbl
|
||||
NROFF=nroff
|
||||
SUF=pr
|
||||
TARGET=-Tlp
|
||||
|
||||
head: ../em.$(SUF)
|
||||
|
||||
FILES = macr.nr title.nr intro.nr mem.nr ispace.nr dspace.nr mapping.nr \
|
||||
types.nr descr.nr env.nr traps.nr mach.nr assem.nr \
|
||||
app.int.nr app.codes.nr app.exam.nr cont.nr
|
||||
|
||||
IOP=$(HOME)/etc/ip_spec.t# # to construct itables from
|
||||
|
||||
../em.$(SUF): $(FILES) itables dispatdummy em.i Makefile
|
||||
$(TBL) $(FILES) | $(NROFF) -mkun $(TARGET) > ../em.$(SUF)
|
||||
|
||||
app.codes.pr: app.codes.nr itables dispatdummy
|
||||
|
||||
itables: $(IOP) ip.awk
|
||||
awk -f ip.awk $(IOP) | sed 's/-/\\-/g' | $(TBL) >itables
|
||||
|
||||
dispatdummy: $(IOP) mkdispatch
|
||||
mkdispatch < $(IOP) > dispatdummy
|
||||
sed -f dispat1.sed < dispatdummy | $(TBL) > dispat1
|
||||
sed -f dispat2.sed < dispatdummy | $(TBL) > dispat2
|
||||
sed -f dispat3.sed < dispatdummy | $(TBL) > dispat3
|
||||
|
||||
mkdispatch: mkdispatch.c
|
||||
$(CC) -I$(HOME)/h -o mkdispatch mkdispatch.c $(HOME)/lib.bin/em_data.a
|
||||
|
||||
.SUFFIXES : .pr .nr
|
||||
.nr.pr: ; $(TBL) macr.nr $*.nr | $(NROFF) -mkun >$@
|
||||
|
||||
clean:
|
||||
rm -f *.pr itables *.out dispatdummy dispat? *.o mkdispatch
|
||||
1122
doc/em/addend.n
Normal file
1122
doc/em/addend.n
Normal file
File diff suppressed because it is too large
Load Diff
11
doc/em/app.int.nr
Normal file
11
doc/em/app.int.nr
Normal file
@ -0,0 +1,11 @@
|
||||
.BP
|
||||
.AP "EM INTERPRETER"
|
||||
.nf
|
||||
.ft CW
|
||||
.lg 0
|
||||
.nr x \w' '
|
||||
.ta \nxu +\nxu +\nxu +\nxu +\nxu +\nxu +\nxu +\nxu +\nxu +\nxu
|
||||
.so em.i
|
||||
.ft P
|
||||
.lg 1
|
||||
.fi
|
||||
488
doc/em/app.nr
Normal file
488
doc/em/app.nr
Normal file
@ -0,0 +1,488 @@
|
||||
.BP
|
||||
.AP "EM INTERPRETER"
|
||||
.nf
|
||||
.ta 8 16 24 32 40 48 56 64 72 80
|
||||
.so em.i
|
||||
.fi
|
||||
.BP
|
||||
.AP "EM CODE TABLES"
|
||||
The following table is used by the assembler for EM machine
|
||||
language.
|
||||
It specifies the opcodes used for each instruction and
|
||||
how arguments are mapped to machine language arguments.
|
||||
The table is presented in three columns,
|
||||
each line in each column contains three or four fields.
|
||||
Each line describes a range of interpreter opcodes by
|
||||
specifying for which instruction the range is used, the type of the
|
||||
opcodes (mini, shortie, etc..) and range for the instruction
|
||||
argument.
|
||||
.A
|
||||
The first field on each line gives the EM instruction mnemonic,
|
||||
the second field gives some flags.
|
||||
If the opcodes are minis or shorties the third field specifies
|
||||
how many minis/shorties are used.
|
||||
The last field gives the number of the (first) interpreter
|
||||
opcode.
|
||||
.N 1
|
||||
Flags :
|
||||
.IS 3
|
||||
.N 1
|
||||
Opcode type, only one of the following may be specified.
|
||||
.PS - 5 " "
|
||||
.PT -
|
||||
opcode without argument
|
||||
.PT m
|
||||
mini
|
||||
.PT s
|
||||
shortie
|
||||
.PT 2
|
||||
opcode with 2-byte signed argument
|
||||
.PT 4
|
||||
opcode with 4-byte signed argument
|
||||
.PT 8
|
||||
opcode with 8-byte signed argument
|
||||
.PE
|
||||
Secondary (escaped) opcodes.
|
||||
.PS - 5 " "
|
||||
.PT e
|
||||
The opcode thus marked is in the secondary opcode group instead
|
||||
of the primary
|
||||
.PE
|
||||
restrictions on arguments
|
||||
.PS - 5 " "
|
||||
.PT N
|
||||
Negative arguments only
|
||||
.PT P
|
||||
Positive and zero arguments only
|
||||
.PE
|
||||
mapping of arguments
|
||||
.PS - 5 " "
|
||||
.PT w
|
||||
argument must be divisible by the wordsize and is divided by the
|
||||
wordsize before use as opcode argument.
|
||||
.PT o
|
||||
argument ( possibly after division ) must be >= 1 and is
|
||||
decremented before use as opcode argument
|
||||
.PE
|
||||
.IE
|
||||
If the opcode type is 2,4 or 8 the resulting argument is used as
|
||||
opcode argument (least significant byte first).
|
||||
.N
|
||||
If the opcode type is mini, the argument is added
|
||||
to the first opcode - if in range - .
|
||||
If the argument is negative, the absolute value minus one is
|
||||
used in the algorithm above.
|
||||
.N
|
||||
For shorties with positive arguments the first opcode is used
|
||||
for arguments in the range 0..255, the second for the range
|
||||
256..511, etc..
|
||||
For shorties with negative arguments the first opcode is used
|
||||
for arguments in the range -1..-256, the second for the range
|
||||
-257..-512, etc..
|
||||
The byte following the opcode contains the least significant
|
||||
byte of the argument.
|
||||
First some examples of these specifications.
|
||||
.PS - 5
|
||||
.PT "aar mwPo 1 34"
|
||||
Indicates that opcode 34 is used as a mini for Positive
|
||||
instruction arguments only.
|
||||
The w and o indicate division and decrementing of the
|
||||
instruction argument.
|
||||
Because the resulting argument must be zero ( only opcode 34 may be used
|
||||
), this mini can only be used for instruction argument 2.
|
||||
Conclusion: opcode 34 is for "AAR 2".
|
||||
.PT "adp sP 1 41"
|
||||
Opcode 41 is used as shortie for ADP with arguments in the range
|
||||
0..255.
|
||||
.PT "bra sN 2 60"
|
||||
Opcode 60 is used as shortie for BRA with arguments -1..-256,
|
||||
61 is used for arguments -257..-512.
|
||||
.PT "zer e- 145"
|
||||
Escaped opcode 145 is used for ZER.
|
||||
.PE
|
||||
The interpreter opcode table:
|
||||
.N 1
|
||||
.IS 3
|
||||
.DS B
|
||||
.so itables
|
||||
.DE 0
|
||||
.IE
|
||||
.P
|
||||
The table above results in the following dispatch tables.
|
||||
Dispatch tables are used by interpreters to jump to the
|
||||
routines implementing the EM instructions, indexed by the next opcode.
|
||||
Each line of the dispatch tables gives the routine names
|
||||
of eight consecutive opcodes, preceded by the first opcode number
|
||||
on that line.
|
||||
Routine names consist of an EM mnemonic followed by a suffix.
|
||||
The suffices show the encoding used for each opcode.
|
||||
.N
|
||||
The following suffices exist:
|
||||
.N 1
|
||||
.VS 1 0
|
||||
.IS 4
|
||||
.PS - 11
|
||||
.PT .z
|
||||
no arguments
|
||||
.PT .l
|
||||
16-bit argument
|
||||
.PT .lw
|
||||
16-bit argument divided by the wordsize
|
||||
.PT .p
|
||||
positive 16-bit argument
|
||||
.PT .pw
|
||||
positive 16-bit argument divided by the wordsize
|
||||
.PT .n
|
||||
negative 16-bit argument
|
||||
.PT .nw
|
||||
negative 16-bit argument divided by the wordsize
|
||||
.PT .s<num>
|
||||
shortie with <num> as high order argument byte
|
||||
.PT .sw<num>
|
||||
shortie with argument divided by the wordsize
|
||||
.PT .<num>
|
||||
mini with <num> as argument
|
||||
.PT .<num>W
|
||||
mini with <num>*wordsize as argument
|
||||
.PE 3
|
||||
<num> is a possibly negative integer.
|
||||
.VS 1 1
|
||||
.IE
|
||||
The dispatch table for the 256 primary opcodes:
|
||||
.DS B
|
||||
0 loc.0 loc.1 loc.2 loc.3 loc.4 loc.5 loc.6 loc.7
|
||||
8 loc.8 loc.9 loc.10 loc.11 loc.12 loc.13 loc.14 loc.15
|
||||
16 loc.16 loc.17 loc.18 loc.19 loc.20 loc.21 loc.22 loc.23
|
||||
24 loc.24 loc.25 loc.26 loc.27 loc.28 loc.29 loc.30 loc.31
|
||||
32 loc.32 loc.33 aar.1W adf.s0 adi.1W adi.2W adp.l adp.1
|
||||
40 adp.2 adp.s0 adp.s-1 ads.1W and.1W asp.1W asp.2W asp.3W
|
||||
48 asp.4W asp.5W asp.w0 beq.l beq.s0 bge.s0 bgt.s0 ble.s0
|
||||
56 blm.s0 blt.s0 bne.s0 bra.l bra.s-1 bra.s-2 bra.s0 bra.s1
|
||||
64 cal.1 cal.2 cal.3 cal.4 cal.5 cal.6 cal.7 cal.8
|
||||
72 cal.9 cal.10 cal.11 cal.12 cal.13 cal.14 cal.15 cal.16
|
||||
80 cal.17 cal.18 cal.19 cal.20 cal.21 cal.22 cal.23 cal.24
|
||||
88 cal.25 cal.26 cal.27 cal.28 cal.s0 cff.z cif.z cii.z
|
||||
96 cmf.s0 cmi.1W cmi.2W cmp.z cms.s0 csa.1W csb.1W dec.z
|
||||
104 dee.w0 del.w-1 dup.1W dvf.s0 dvi.1W fil.l inc.z ine.lw
|
||||
112 ine.w0 inl.-1W inl.-2W inl.-3W inl.w-1 inn.s0 ior.1W ior.s0
|
||||
120 lae.l lae.w0 lae.w1 lae.w2 lae.w3 lae.w4 lae.w5 lae.w6
|
||||
128 lal.p lal.n lal.0 lal.-1 lal.w0 lal.w-1 lal.w-2 lar.W
|
||||
136 ldc.0 lde.lw lde.w0 ldl.0 ldl.w-1 lfr.1W lfr.2W lfr.s0
|
||||
144 lil.w-1 lil.w0 lil.0 lil.1W lin.l lin.s0 lni.z loc.l
|
||||
152 loc.-1 loc.s0 loc.s-1 loe.lw loe.w0 loe.w1 loe.w2 loe.w3
|
||||
160 loe.w4 lof.l lof.1W lof.2W lof.3W lof.4W lof.s0 loi.l
|
||||
168 loi.1 loi.1W loi.2W loi.3W loi.4W loi.s0 lol.pw lol.nw
|
||||
176 lol.0 lol.1W lol.2W lol.3W lol.-1W lol.-2W lol.-3W lol.-4W
|
||||
184 lol.-5W lol.-6W lol.-7W lol.-8W lol.w0 lol.w-1 lxa.1 lxl.1
|
||||
192 lxl.2 mlf.s0 mli.1W mli.2W rck.1W ret.0 ret.1W ret.s0
|
||||
200 rmi.1W sar.1W sbf.s0 sbi.1W sbi.2W sdl.w-1 set.s0 sil.w-1
|
||||
208 sil.w0 sli.1W ste.lw ste.w0 ste.w1 ste.w2 stf.l stf.W
|
||||
216 stf.2W stf.s0 sti.1 sti.1W sti.2W sti.3W sti.4W sti.s0
|
||||
224 stl.pw stl.nw stl.0 stl.1W stl.-1W stl.-2W stl.-3W stl.-4W
|
||||
232 stl.-5W stl.w-1 teq.z tgt.z tlt.z tne.z zeq.l zeq.s0
|
||||
240 zeq.s1 zer.s0 zge.s0 zgt.s0 zle.s0 zlt.s0 zne.s0 zne.s-1
|
||||
248 zre.lw zre.w0 zrl.-1W zrl.-2W zrl.w-1 zrl.nw escape1 escape2
|
||||
.DE 2
|
||||
The list of secondary opcodes (escape1):
|
||||
.N 1
|
||||
.DS B
|
||||
0 aar.l aar.z adf.l adf.z adi.l adi.z ads.l ads.z
|
||||
8 adu.l adu.z and.l and.z asp.lw ass.l ass.z bge.l
|
||||
16 bgt.l ble.l blm.l bls.l bls.z blt.l bne.l cai.z
|
||||
24 cal.l cfi.z cfu.z ciu.z cmf.l cmf.z cmi.l cmi.z
|
||||
32 cms.l cms.z cmu.l cmu.z com.l com.z csa.l csa.z
|
||||
40 csb.l csb.z cuf.z cui.z cuu.z dee.lw del.pw del.nw
|
||||
48 dup.l dus.l dus.z dvf.l dvf.z dvi.l dvi.z dvu.l
|
||||
56 dvu.z fef.l fef.z fif.l fif.z inl.pw inl.nw inn.l
|
||||
64 inn.z ior.l ior.z lar.l lar.z ldc.l ldf.l ldl.pw
|
||||
72 ldl.nw lfr.l lil.pw lil.nw lim.z los.l los.z lor.s0
|
||||
80 lpi.l lxa.l lxl.l mlf.l mlf.z mli.l mli.z mlu.l
|
||||
88 mlu.z mon.z ngf.l ngf.z ngi.l ngi.z nop.z rck.l
|
||||
96 rck.z ret.l rmi.l rmi.z rmu.l rmu.z rol.l rol.z
|
||||
104 ror.l ror.z rtt.z sar.l sar.z sbf.l sbf.z sbi.l
|
||||
112 sbi.z sbs.l sbs.z sbu.l sbu.z sde.l sdf.l sdl.pw
|
||||
120 sdl.nw set.l set.z sig.z sil.pw sil.nw sim.z sli.l
|
||||
128 sli.z slu.l slu.z sri.l sri.z sru.l sru.z sti.l
|
||||
136 sts.l sts.z str.s0 tge.z tle.z trp.z xor.l xor.z
|
||||
144 zer.l zer.z zge.l zgt.l zle.l zlt.l zne.l zrf.l
|
||||
152 zrf.z zrl.pw dch.z exg.s0 exg.l exg.z lpb.z gto.l
|
||||
.DE 2
|
||||
Finally, the list of opcodes with four byte arguments (escape2).
|
||||
.DS
|
||||
|
||||
0 loc
|
||||
.DE 0
|
||||
.BP
|
||||
.AP "AN EXAMPLE PROGRAM"
|
||||
.DS B
|
||||
1 program example(output);
|
||||
2 {This program just demonstrates typical EM code.}
|
||||
3 type rec = record r1: integer; r2:real; r3: boolean end;
|
||||
4 var mi: integer; mx:real; r:rec;
|
||||
5
|
||||
6 function sum(a,b:integer):integer;
|
||||
7 begin
|
||||
8 sum := a + b
|
||||
9 end;
|
||||
10
|
||||
11 procedure test(var r: rec);
|
||||
12 label 1;
|
||||
13 var i,j: integer;
|
||||
14 x,y: real;
|
||||
15 b: boolean;
|
||||
16 c: char;
|
||||
17 a: array[1..100] of integer;
|
||||
18
|
||||
19 begin
|
||||
20 j := 1;
|
||||
21 i := 3 * j + 6;
|
||||
22 x := 4.8;
|
||||
23 y := x/0.5;
|
||||
24 b := true;
|
||||
25 c := 'z';
|
||||
26 for i:= 1 to 100 do a[i] := i * i;
|
||||
27 r.r1 := j+27;
|
||||
28 r.r3 := b;
|
||||
29 r.r2 := x+y;
|
||||
30 i := sum(r.r1, a[j]);
|
||||
31 while i > 0 do begin j := j + r.r1; i := i - 1 end;
|
||||
32 with r do begin r3 := b; r2 := x+y; r1 := 0 end;
|
||||
33 goto 1;
|
||||
34 1: writeln(j, i:6, x:9:3, b)
|
||||
35 end; {test}
|
||||
36 begin {main program}
|
||||
37 mx := 15.96;
|
||||
38 mi := 99;
|
||||
39 test(r)
|
||||
40 end.
|
||||
.DE 0
|
||||
.BP
|
||||
The EM code as produced by the Pascal-VU compiler is given below. Comments
|
||||
have been added manually. Note that this code has already been optimized.
|
||||
.DS B
|
||||
mes 2,2,2 ; wordsize 2, pointersize 2
|
||||
.1
|
||||
rom 't.p\e000' ; the name of the source file
|
||||
hol 552,-32768,0 ; externals and buf occupy 552 bytes
|
||||
exp $sum ; sum can be called from other modules
|
||||
pro $sum,2 ; procedure sum; 2 bytes local storage
|
||||
lin 8 ; code from source line 8
|
||||
ldl 0 ; load two locals ( a and b )
|
||||
adi 2 ; add them
|
||||
ret 2 ; return the result
|
||||
end 2 ; end of procedure ( still two bytes local storage )
|
||||
.2
|
||||
rom 1,99,2 ; descriptor of array a[]
|
||||
exp $test ; the compiler exports all level 0 procedures
|
||||
pro $test,226 ; procedure test, 226 bytes local storage
|
||||
.3
|
||||
rom 4.8F8 ; assemble Floating point 4.8 (8 bytes) in
|
||||
.4 ; global storage
|
||||
rom 0.5F8 ; same for 0.5
|
||||
mes 3,-226,2,2 ; compiler temporary not referenced by address
|
||||
mes 3,-24,2,0 ; the same is true for i, j, b and c in test
|
||||
mes 3,-22,2,0
|
||||
mes 3,-4,2,0
|
||||
mes 3,-2,2,0
|
||||
mes 3,-20,8,0 ; and for x and y
|
||||
mes 3,-12,8,0
|
||||
lin 20 ; maintain source line number
|
||||
loc 1
|
||||
stl -4 ; j := 1
|
||||
lni ; lin 21 prior to optimization
|
||||
lol -4
|
||||
loc 3
|
||||
mli 2
|
||||
loc 6
|
||||
adi 2
|
||||
stl -2 ; i := 3 * j + 6
|
||||
lni ; lin 22 prior to optimization
|
||||
lae .3
|
||||
loi 8
|
||||
lal -12
|
||||
sti 8 ; x := 4.8
|
||||
lni ; lin 23 prior to optimization
|
||||
lal -12
|
||||
loi 8
|
||||
lae .4
|
||||
loi 8
|
||||
dvf 8
|
||||
lal -20
|
||||
sti 8 ; y := x / 0.5
|
||||
lni ; lin 24 prior to optimization
|
||||
loc 1
|
||||
stl -22 ; b := true
|
||||
lni ; lin 25 prior to optimization
|
||||
loc 122
|
||||
stl -24 ; c := 'z'
|
||||
lni ; lin 26 prior to optimization
|
||||
loc 1
|
||||
stl -2 ; for i:= 1
|
||||
2
|
||||
lol -2
|
||||
dup 2
|
||||
mli 2 ; i*i
|
||||
lal -224
|
||||
lol -2
|
||||
lae .2
|
||||
sar 2 ; a[i] :=
|
||||
lol -2
|
||||
loc 100
|
||||
beq *3 ; to 100 do
|
||||
inl -2 ; increment i and loop
|
||||
bra *2
|
||||
3
|
||||
lin 27
|
||||
lol -4
|
||||
loc 27
|
||||
adi 2 ; j + 27
|
||||
sil 0 ; r.r1 :=
|
||||
lni ; lin 28 prior to optimization
|
||||
lol -22 ; b
|
||||
lol 0
|
||||
stf 10 ; r.r3 :=
|
||||
lni ; lin 29 prior to optimization
|
||||
lal -20
|
||||
loi 16
|
||||
adf 8 ; x + y
|
||||
lol 0
|
||||
adp 2
|
||||
sti 8 ; r.r2 :=
|
||||
lni ; lin 23 prior to optimization
|
||||
lal -224
|
||||
lol -4
|
||||
lae .2
|
||||
lar 2 ; a[j]
|
||||
lil 0 ; r.r1
|
||||
cal $sum ; call now
|
||||
asp 4 ; remove parameters from stack
|
||||
lfr 2 ; get function result
|
||||
stl -2 ; i :=
|
||||
4
|
||||
lin 31
|
||||
lol -2
|
||||
zle *5 ; while i > 0 do
|
||||
lol -4
|
||||
lil 0
|
||||
adi 2
|
||||
stl -4 ; j := j + r.r1
|
||||
del -2 ; i := i - 1
|
||||
bra *4 ; loop
|
||||
5
|
||||
lin 32
|
||||
lol 0
|
||||
stl -226 ; make copy of address of r
|
||||
lol -22
|
||||
lol -226
|
||||
stf 10 ; r3 := b
|
||||
lal -20
|
||||
loi 16
|
||||
adf 8
|
||||
lol -226
|
||||
adp 2
|
||||
sti 8 ; r2 := x + y
|
||||
loc 0
|
||||
sil -226 ; r1 := 0
|
||||
lin 34 ; note the abscence of the unnecesary jump
|
||||
lae 22 ; address of output structure
|
||||
lol -4
|
||||
cal $_wri ; write integer with default width
|
||||
asp 4 ; pop parameters
|
||||
lae 22
|
||||
lol -2
|
||||
loc 6
|
||||
cal $_wsi ; write integer width 6
|
||||
asp 6
|
||||
lae 22
|
||||
lal -12
|
||||
loi 8
|
||||
loc 9
|
||||
loc 3
|
||||
cal $_wrf ; write fixed format real, width 9, precision 3
|
||||
asp 14
|
||||
lae 22
|
||||
lol -22
|
||||
cal $_wrb ; write boolean, default width
|
||||
asp 4
|
||||
lae 22
|
||||
cal $_wln ; writeln
|
||||
asp 2
|
||||
ret 0 ; return, no result
|
||||
end 226
|
||||
exp $_main
|
||||
pro $_main,0 ; main program
|
||||
.6
|
||||
con 2,-1,22 ; description of external files
|
||||
.5
|
||||
rom 15.96F8
|
||||
fil .1 ; maintain source file name
|
||||
lae .6 ; description of external files
|
||||
lae 0 ; base of hol area to relocate buffer addresses
|
||||
cal $_ini ; initialize files, etc...
|
||||
asp 4
|
||||
lin 37
|
||||
lae .5
|
||||
loi 8
|
||||
lae 2
|
||||
sti 8 ; mx := 15.96
|
||||
lni ; lin 38 prior to optimization
|
||||
loc 99
|
||||
ste 0 ; mi := 99
|
||||
lni ; lin 39 prior to optimization
|
||||
lae 10 ; address of r
|
||||
cal $test
|
||||
asp 2
|
||||
loc 0 ; normal exit
|
||||
cal $_hlt ; cleanup and finish
|
||||
asp 2
|
||||
end 0
|
||||
mes 5 ; reals were used
|
||||
.DE 0
|
||||
The compact code corresponding to the above program is listed below.
|
||||
Read it horizontally, line by line, not column by column.
|
||||
Each number represents a byte of compact code, printed in decimal.
|
||||
The first two bytes form the magic word.
|
||||
.N 1
|
||||
.IS 3
|
||||
.DS B
|
||||
173 0 159 122 122 122 255 242 1 161 250 124 116 46 112 0
|
||||
255 156 245 40 2 245 0 128 120 155 249 123 115 117 109 160
|
||||
249 123 115 117 109 122 67 128 63 120 3 122 88 122 152 122
|
||||
242 2 161 121 219 122 255 155 249 124 116 101 115 116 160 249
|
||||
124 116 101 115 116 245 226 0 242 3 161 253 128 123 52 46
|
||||
56 255 242 4 161 253 128 123 48 46 53 255 159 123 245 30
|
||||
255 122 122 255 159 123 96 122 120 255 159 123 98 122 120 255
|
||||
159 123 116 122 120 255 159 123 118 122 120 255 159 123 100 128
|
||||
120 255 159 123 108 128 120 255 67 140 69 121 113 116 68 73
|
||||
116 69 123 81 122 69 126 3 122 113 118 68 57 242 3 72
|
||||
128 58 108 112 128 68 58 108 72 128 57 242 4 72 128 44
|
||||
128 58 100 112 128 68 69 121 113 98 68 69 245 122 0 113
|
||||
96 68 69 121 113 118 182 73 118 42 122 81 122 58 245 32
|
||||
255 73 118 57 242 2 94 122 73 118 69 220 10 123 54 118
|
||||
18 122 183 67 147 73 116 69 147 3 122 104 120 68 73 98
|
||||
73 120 111 130 68 58 100 72 136 2 128 73 120 4 122 112
|
||||
128 68 58 245 32 255 73 116 57 242 2 59 122 65 120 20
|
||||
249 123 115 117 109 8 124 64 122 113 118 184 67 151 73 118
|
||||
128 125 73 116 65 120 3 122 113 116 41 118 18 124 185 67
|
||||
152 73 120 113 245 30 255 73 98 73 245 30 255 111 130 58
|
||||
100 72 136 2 128 73 245 30 255 4 122 112 128 69 120 104
|
||||
245 30 255 67 154 57 142 73 116 20 249 124 95 119 114 105
|
||||
8 124 57 142 73 118 69 126 20 249 124 95 119 115 105 8
|
||||
126 57 142 58 108 72 128 69 129 69 123 20 249 124 95 119
|
||||
114 102 8 134 57 142 73 98 20 249 124 95 119 114 98 8
|
||||
124 57 142 20 249 124 95 119 108 110 8 122 88 120 152 245
|
||||
226 0 155 249 125 95 109 97 105 110 160 249 125 95 109 97
|
||||
105 110 120 242 6 151 122 119 142 255 242 5 161 253 128 125
|
||||
49 53 46 57 54 255 50 242 1 57 242 6 57 120 20 249
|
||||
124 95 105 110 105 8 124 67 157 57 242 5 72 128 57 122
|
||||
112 128 68 69 219 110 120 68 57 130 20 249 124 116 101 115
|
||||
116 8 122 69 120 20 249 124 95 104 108 116 8 122 152 120
|
||||
159 124 160 255 159 125 255
|
||||
.DE 0
|
||||
.IE
|
||||
.MS T A 0
|
||||
.ME
|
||||
.BP
|
||||
.MS B A 0
|
||||
.ME
|
||||
.CT
|
||||
32
doc/em/int/Makefile
Normal file
32
doc/em/int/Makefile
Normal file
@ -0,0 +1,32 @@
|
||||
CFLAGS=-O
|
||||
HOME=../../..
|
||||
|
||||
install \
|
||||
all: em emdmp tables
|
||||
|
||||
tables: mktables $(HOME)/etc/ip_spec.t
|
||||
mktables $(HOME)/etc/ip_spec.t tables
|
||||
|
||||
mktables: mktables.c $(HOME)/h/em_spec.h $(HOME)/h/em_flag.h \
|
||||
$(HOME)/lib.bin/em_data.a $(HOME)/h/ip_spec.h
|
||||
$(CC) -I$(HOME)/h -O -o mktables mktables.c $(HOME)/lib.bin/em_data.a
|
||||
|
||||
em.out: em.p
|
||||
apc -mint -O em.p >emerrs ; mv e.out em.out
|
||||
|
||||
em: em.p
|
||||
apc -O -i em.p >emerrs ; mv a.out em
|
||||
|
||||
nem.p: em.p
|
||||
sed -e '/maxadr = t16/s//maxadr =t15/' -e '/maxdata = 8191; /s//maxdata = 14335;/' -e '/ adr=.*long/s// adr= 0..maxadr/' <em.p >nem.p
|
||||
|
||||
nem: nem.p
|
||||
apc -O -i nem.p >emerrs ; mv a.out nem
|
||||
|
||||
emdmp: emdmp.c
|
||||
$(CC) -I$(HOME)/h -I$(HOME)/config -o emdmp -O emdmp.c
|
||||
|
||||
cmp:
|
||||
|
||||
pr:
|
||||
@pr em.p mktables.c emdmp.c
|
||||
376
doc/em/iotrap.nr
Normal file
376
doc/em/iotrap.nr
Normal file
@ -0,0 +1,376 @@
|
||||
.SN 8
|
||||
.VS 1 0
|
||||
.BP
|
||||
.S1 "ENVIRONMENT INTERACTIONS"
|
||||
EM programs can interact with their environment in three ways.
|
||||
Two, starting/stopping and monitor calls, are dealt with in this chapter.
|
||||
The remaining way to interact, interrupts, will be treated
|
||||
together with traps in chapter 9.
|
||||
.S2 "Program starting and stopping"
|
||||
EM user programs start with a call to a procedure called
|
||||
m_a_i_n.
|
||||
The assembler and backends look for the definition of a procedure
|
||||
with this name in their input.
|
||||
The call passes three parameters to the procedure.
|
||||
The parameters are similar to the parameters supplied by the
|
||||
UNIX
|
||||
.FS
|
||||
UNIX is a Trademark of Bell Laboratories.
|
||||
.FE
|
||||
operating system to C programs.
|
||||
These parameters are often called
|
||||
.BW argc ,
|
||||
.B argv
|
||||
and
|
||||
.BW envp .
|
||||
Argc is the parameter nearest to LB and is a wordsized integer.
|
||||
The other two are pointers to the first element of an array of
|
||||
string pointers.
|
||||
.N
|
||||
The
|
||||
.B argv
|
||||
array contains
|
||||
.B argc
|
||||
strings, the first of which contains the program call name.
|
||||
The other strings in the
|
||||
.B argv
|
||||
array are the program parameters.
|
||||
.P
|
||||
The
|
||||
.B envp
|
||||
array contains strings in the form "name=string", where 'name'
|
||||
is the name of an environment variable and string its value.
|
||||
The
|
||||
.B envp
|
||||
is terminated by a zero pointer.
|
||||
.P
|
||||
An EM user program stops if the program returns from the first
|
||||
invocation of m_a_i_n.
|
||||
The contents of the function return area are used to procure a
|
||||
wordsized program return code.
|
||||
EM programs also stop when traps and interrupts occur that are
|
||||
not caught and when the exit monitor call is executed.
|
||||
.S2 "Input/Output and other monitor calls"
|
||||
EM differs from most conventional machines in that it has high level i/o
|
||||
instructions.
|
||||
Typical instructions are OPEN FILE and READ FROM FILE instead
|
||||
of low level instructions such as setting and clearing
|
||||
bits in device registers.
|
||||
By providing such high level i/o primitives, the task of implementing
|
||||
EM on various non EM machines is made considerably easier.
|
||||
.P
|
||||
I/O is initiated by the MON instruction, which expects an iocode on top
|
||||
of the stack.
|
||||
Often there are also parameters which are pushed on the
|
||||
stack in reverse order, that is: last
|
||||
parameter first.
|
||||
Some i/o functions also provide results, which are returned on the stack.
|
||||
In the list of monitor calls we use several types of parameters and results,
|
||||
these types consist of integers and unsigneds of varying sizes, but never
|
||||
smaller than the wordsize, and the two pointer types.
|
||||
.N 1
|
||||
The names of the types used are:
|
||||
.IS 4
|
||||
.PS - 10
|
||||
.PT int
|
||||
an integer of wordsize
|
||||
.PT int2
|
||||
an integer whose size is the maximum of the wordsize and 2
|
||||
bytes
|
||||
.PT int4
|
||||
an integer whose size is the maximum of the wordsize and 4
|
||||
bytes
|
||||
.PT intp
|
||||
an integer with the size of a pointer
|
||||
.PT uns2
|
||||
an unsigned integer whose size is the maximum of the wordsize and 2
|
||||
.PT unsp
|
||||
an unsigned integer with the size of a pointer
|
||||
.PT ptr
|
||||
a pointer into data space
|
||||
.PE 1
|
||||
.IE 0
|
||||
The table below lists the i/o codes with their results and
|
||||
parameters.
|
||||
This list is similar to the system calls of the UNIX Version 7
|
||||
operating system.
|
||||
.BP
|
||||
.A
|
||||
To execute a monitor call, proceed as follows:
|
||||
.IS 2
|
||||
.N 1
|
||||
.PS a 4 "" )
|
||||
.PT
|
||||
Stack the parameters, in reverse order, last parameter first.
|
||||
.PT
|
||||
Push the monitor call number (iocode) onto the stack.
|
||||
.PT
|
||||
Execute the MON instruction.
|
||||
.PE 1
|
||||
.IE
|
||||
An error code is present on the top of the stack after
|
||||
execution of most monitor calls.
|
||||
If this error code is zero, the call performed the action
|
||||
requested and the results are available on top of the stack.
|
||||
Non-zero error codes indicate a failure, in this case no
|
||||
results are available and the error code has been pushed twice.
|
||||
This construction enables programs to test for failure with a
|
||||
single instruction (~TEQ or TNE~) and still find out the cause of
|
||||
the failure.
|
||||
The result name 'e' is reserved for the error code.
|
||||
.N 1
|
||||
List of monitor calls.
|
||||
.DS B
|
||||
number name parameters results function
|
||||
|
||||
1 Exit status:int Terminate this process
|
||||
2 Fork e,flag,pid:int Spawn new process
|
||||
3 Read fildes:int;buf:ptr;nbytes:unsp
|
||||
e:int;rbytes:unsp Read from file
|
||||
4 Write fildes:int;buf:ptr;nbytes:unsp
|
||||
e:int;wbytes:unsp Write on a file
|
||||
5 Open string:ptr;flag:int
|
||||
e,fildes:int Open file for read and/or write
|
||||
6 Close fildes:int e:int Close a file
|
||||
7 Wait e:int;status,pid:int2
|
||||
Wait for child
|
||||
8 Creat string:ptr;mode:int
|
||||
e,fildes:int Create a new file
|
||||
9 Link string1,string2:ptr
|
||||
e:int Link to a file
|
||||
10 Unlink string:ptr e:int Remove directory entry
|
||||
12 Chdir string:ptr e:int Change default directory
|
||||
14 Mknod string:ptr;mode,addr:int2
|
||||
e:int Make a special file
|
||||
15 Chmod string:ptr;mode:int2
|
||||
e:int Change mode of file
|
||||
16 Chown string:ptr;owner,group:int2
|
||||
e:int Change owner/group of a file
|
||||
18 Stat string,statbuf:ptr
|
||||
e:int Get file status
|
||||
19 Lseek fildes:int;off:int4;whence:int
|
||||
e:int;oldoff:int4 Move read/write pointer
|
||||
20 Getpid pid:int2 Get process identification
|
||||
21 Mount special,string:ptr;rwflag:int
|
||||
e:int Mount file system
|
||||
22 Umount special:ptr e:int Unmount file system
|
||||
23 Setuid userid:int2 e:int Set user ID
|
||||
24 Getuid e_uid,r_uid:int2 Get user ID
|
||||
25 Stime time:int4 e:int Set time and date
|
||||
26 Ptrace request:int;pid:int2;addr:ptr;data:int
|
||||
e,value:int Process trace
|
||||
27 Alarm seconds:uns2 previous:uns2 Schedule signal
|
||||
28 Fstat fildes:int;statbuf:ptr
|
||||
e:int Get file status
|
||||
29 Pause Stop until signal
|
||||
30 Utime string,timep:ptr
|
||||
e:int Set file times
|
||||
33 Access string,mode:int e:int Determine file accessibility
|
||||
34 Nice incr:int Set program priority
|
||||
35 Ftime bufp:ptr e:int Get date and time
|
||||
36 Sync Update filesystem
|
||||
37 Kill pid:int2;sig:int
|
||||
e:int Send signal to a process
|
||||
41 Dup fildes,newfildes:int
|
||||
e,fildes:int Duplicate a file descriptor
|
||||
42 Pipe e,w_des,r_des:int Create a pipe
|
||||
43 Times buffer:ptr Get process times
|
||||
44 Profil buff:ptr;bufsiz,offset,scale:intp Execution time profile
|
||||
46 Setgid gid:int2 e:int Set group ID
|
||||
47 Getgid e_gid,r_gid:int Get group ID
|
||||
48 Sigtrp trapno,signo:int
|
||||
e,prevtrap:int See below
|
||||
51 Acct file:ptr e:int Turn accounting on or off
|
||||
53 Lock flag:int e:int Lock a process
|
||||
54 Ioctl fildes,request:int;argp:ptr
|
||||
e:int Control device
|
||||
56 Mpxcall cmd:int;vec:ptr e:int Multiplexed file handling
|
||||
59 Exece name,argv,envp:ptr
|
||||
e:int Execute a file
|
||||
60 Umask complmode:int2 oldmask:int2 Set file creation mode mask
|
||||
61 Chroot string:ptr e:int Change root directory
|
||||
.DE 1
|
||||
Codes 0, 11, 13, 17, 31, 32, 38, 39, 40, 45, 49, 50, 52,
|
||||
55, 57, 58, 62, and 63 are
|
||||
not used.
|
||||
.P
|
||||
All monitor calls, except fork and sigtrp
|
||||
are the same as the UNIX version 7 system calls.
|
||||
.P
|
||||
The sigtrp entry maps UNIX signals onto EM interrupts.
|
||||
Normally, trapno is in the range 0 to 252.
|
||||
In that case it requests that signal signo
|
||||
will cause trap trapno to occur.
|
||||
When given trap number -2, default signal handling is reset, and when given
|
||||
trap number -3, the signal is ignored.
|
||||
.P
|
||||
The flag returned by fork is 1 in the child process and 0 in
|
||||
the parent.
|
||||
The pid returned is the process-id of the other process.
|
||||
.BP
|
||||
.S1 "TRAPS AND INTERRUPTS"
|
||||
EM provides a means for the user program to catch all traps
|
||||
generated by the program itself, the hardware, or external conditions.
|
||||
This mechanism uses five instructions: LIM, SIM, SIG, TRP and RTT.
|
||||
This section of the manual may be omitted on the first reading since it
|
||||
presupposes knowledge of the EM instruction set.
|
||||
.P
|
||||
The action taken when a trap occures is determined by the value
|
||||
of an internal EM trap register.
|
||||
This register contains a pointer to a procedure.
|
||||
Initially the pointer used is zero and all traps halt the
|
||||
program with, hopefully, a useful message to the outside world.
|
||||
The SIG instruction can be used to alter the trap register,
|
||||
it pops a procedure pointer from the
|
||||
stack into the trap register.
|
||||
When a trap occurs after storing a nonzero value in the trap
|
||||
register, the procedure pointed to by the trap register
|
||||
is called with the trap number
|
||||
as the only parameter (see below).
|
||||
SIG returns the previous value of the trap register on the
|
||||
stack.
|
||||
Two consecutive SIGs are a no-op.
|
||||
When a trap occurs, the trap register is reset to its initial
|
||||
condition, to prevent recursive traps from hanging the machine up,
|
||||
e.g. stack overflow in the stack overflow handling procedure.
|
||||
.P
|
||||
The runtime systems for some languages need to ignore some EM
|
||||
traps.
|
||||
EM offers a feature called the ignore mask.
|
||||
It contains one bit for each of the lowest 16 trap numbers.
|
||||
The bits are numbered 0 to 15, with the least significant bit
|
||||
having number 0.
|
||||
If a certain bit is 1 the corresponding trap never
|
||||
occurs and processing simply continues.
|
||||
The actions performed by the offending instruction are
|
||||
described by the Pascal program in appendix A.
|
||||
.N
|
||||
If the bit is 0, traps are not ignored.
|
||||
The instructions LIM and SIM allow copying and replacement of
|
||||
the ignore mask.~
|
||||
.P
|
||||
The TRP instruction generates a trap, the trap number being found on the
|
||||
stack.
|
||||
This is, among other things,
|
||||
useful for library procedures and runtime systems.
|
||||
It can also be used by a low level trap procedure to pass the trap to a
|
||||
higher level one (see example below).
|
||||
.P
|
||||
The RTT instruction returns from the trap procedure and continues after the
|
||||
trap.
|
||||
In the list below all traps marked with an asterisk ('*') are
|
||||
considered to be fatal and it is explicitly undefined what happens if
|
||||
you try to restart after the trap.
|
||||
.P
|
||||
The way a trap procedure is called is completely compatible
|
||||
with normal calling conventions. The only way a trap procedure
|
||||
differs from normal procedures is the return. It has to use RTT instead
|
||||
of RET. This is necessary because the complete runtime status is saved on the
|
||||
stack before calling the procedure and all this status has to be reloaded.
|
||||
Error numbers are in the range 0 to 252.
|
||||
The trap numbers are divided into three categories:
|
||||
.IS 4
|
||||
.N 1
|
||||
.PS - 10
|
||||
.PT ~~0-~63
|
||||
EM machine errors, e.g. illegal instruction.
|
||||
.PS - 8
|
||||
.PT ~0-15
|
||||
maskable
|
||||
.PT 16-63
|
||||
not maskable
|
||||
.PE
|
||||
.PT ~64-127
|
||||
Reserved for use by compilers, run time systems, etc.
|
||||
.PT 128-252
|
||||
Available for user programs.
|
||||
.PE 1
|
||||
.IE
|
||||
EM machine errors are numbered as follows:
|
||||
.DS I 5
|
||||
.TS
|
||||
tab(@);
|
||||
n l l.
|
||||
0@EARRAY@Array bound error
|
||||
1@ERANGE@Range bound error
|
||||
2@ESET@Set bound error
|
||||
3@EIOVFL@Integer overflow
|
||||
4@EFOVFL@Floating overflow
|
||||
5@EFUNFL@Floating underflow
|
||||
6@EIDIVZ@Divide by 0
|
||||
7@EFDIVZ@Divide by 0.0
|
||||
8@EIUND@Undefined integer
|
||||
9@EFUND@Undefined float
|
||||
10@ECONV@Conversion error
|
||||
16*@ESTACK@Stack overflow
|
||||
17*@EHEAP@Heap overflow
|
||||
18*@EILLINS@Illegal instruction
|
||||
19*@EODDZ@Illegal size argument
|
||||
20*@ECASE@Case error
|
||||
21*@EMEMFLT@Addressing non existent memory
|
||||
22*@EBADPTR@Bad pointer used
|
||||
23*@EBADPC@Program counter out of range
|
||||
24@EBADLAE@Bad argument of LAE
|
||||
25@EBADMON@Bad monitor call
|
||||
26@EBADLIN@Argument of LIN too high
|
||||
27@EBADGTO@GTO descriptor error
|
||||
.TE
|
||||
.DE 0
|
||||
.P
|
||||
As an example,
|
||||
suppose a subprocedure has to be written to do a numeric
|
||||
calculation.
|
||||
When an overflow occurs the computation has to be stopped and
|
||||
the higher level procedure must be resumed.
|
||||
This can be programmed as follows using the mechanism described above:
|
||||
.DS B
|
||||
mes 2,2,2 ; set sizes
|
||||
ersave
|
||||
bss 2,0,0 ; Room to save previous value of trap procedure
|
||||
msave
|
||||
bss 2,0,0 ; Room to save previous value of trap mask
|
||||
|
||||
pro calcule,0 ; entry point
|
||||
lxl 0 ; fill in non-local goto descriptor with LB
|
||||
ste jmpbuf+4
|
||||
lor 1 ; and SP
|
||||
ste jmpbuf+2
|
||||
lim ; get current ignore mask
|
||||
ste msave ; save it
|
||||
lim
|
||||
loc 16 ; bit for EFOVFL
|
||||
ior 2 ; set in mask
|
||||
sim ; ignore EFOVFL from now on
|
||||
lpi $catch ; load procedure identifier
|
||||
sig ; catch wil get all traps now
|
||||
ste ersave ; save previous trap procedure identifier
|
||||
; perform calculation now, possibly generating overflow
|
||||
1 ; label jumped to by catch procedure
|
||||
loe ersave ; get old trap procedure
|
||||
sig ; refer all following trap to old procedure
|
||||
asp 2 ; remove result of sig
|
||||
loe msave ; restore previous mask
|
||||
sim ; done now
|
||||
; load result of calculation
|
||||
ret 2 ; return result
|
||||
jmpbuf
|
||||
con *1,0,0
|
||||
end
|
||||
.DE 0
|
||||
.VS 1 1
|
||||
.DS
|
||||
Example of catch procedure
|
||||
pro catch,0 ; Local procedure that must catch the overflow trap
|
||||
lol 2 ; Load trap number
|
||||
loc 4 ; check for overflow
|
||||
bne *1 ; if other trap, call higher trap procedure
|
||||
gto jmpbuf ; return to procedure calcule
|
||||
1 ; other trap has occurred
|
||||
loe ersave ; previous trap procedure
|
||||
sig ; other procedure will get the traps now
|
||||
asp 2 ; remove the result of sig
|
||||
lol 2 ; stack trap number
|
||||
trp ; call other trap procedure
|
||||
rtt ; if other procedure returns, do the same
|
||||
end
|
||||
.DE
|
||||
2922
doc/em/itables
Normal file
2922
doc/em/itables
Normal file
File diff suppressed because it is too large
Load Diff
5
doc/em/print
Executable file
5
doc/em/print
Executable file
@ -0,0 +1,5 @@
|
||||
|
||||
case $# in
|
||||
1) make "$1".t ; ntlp "$1".t^lpr ;;
|
||||
*) echo $0 heeft een argument nodig ;;
|
||||
esac
|
||||
4
doc/em/show
Executable file
4
doc/em/show
Executable file
@ -0,0 +1,4 @@
|
||||
case $# in
|
||||
1) make $1.t ; ntout $1.t ;;
|
||||
*) echo $0 heeft een argument nodig ;;
|
||||
esac
|
||||
9
doc/lint/Makefile
Normal file
9
doc/lint/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
# $Header$
|
||||
|
||||
FP = frontpage
|
||||
|
||||
DOC = abstract contents chap1 chap2 chap3 chap4 chap5 chap6 chap7\
|
||||
chap8 chap9 appendix_A appendix_B
|
||||
|
||||
../lint.doc: $(FP) $(DOC)
|
||||
cat $(FP) $(DOC) > ../lint.doc
|
||||
18
doc/occam/Makefile
Normal file
18
doc/occam/Makefile
Normal file
@ -0,0 +1,18 @@
|
||||
EMHOME=../..
|
||||
FILES= p0 p1 p2 p3 p4 p5 p6 p7 p8 p9
|
||||
|
||||
PIC=pic
|
||||
EQN=eqn
|
||||
TBL=tbl
|
||||
TARGET=-Tlp
|
||||
../occam.doc: p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 channel.h.t channel.c.t
|
||||
soelim $(FILES) | $(PIC) $(TARGET) | $(TBL) | $(EQN) $(TARGET) > $@
|
||||
|
||||
channel.h.t: $(EMHOME)/h/ocm_chan.h
|
||||
ctot <$(EMHOME)/h/ocm_chan.h >channel.h.t
|
||||
|
||||
channel.c.t: channel.c
|
||||
ctot <channel.c >channel.c.t
|
||||
|
||||
channel.c: $(EMHOME)/lang/occam/lib/tail_ocm.a
|
||||
arch x $(EMHOME)/lang/occam/lib/tail_ocm.a channel.c
|
||||
10
doc/sparc/Makefile
Normal file
10
doc/sparc/Makefile
Normal file
@ -0,0 +1,10 @@
|
||||
# $Header$
|
||||
|
||||
REFER=refer
|
||||
TBL=tbl
|
||||
TARGET=-Tlp
|
||||
PIC=pic
|
||||
GRAP=grap
|
||||
|
||||
../sparc.doc: refs title intro 1 2 3 4 5 A B init
|
||||
$(REFER) -sA+T '-l\", ' -p refs title intro 1 2 3 4 5 A B | $(GRAP) | $(PIC) | $(TBL) | soelim > $@
|
||||
8
doc/top/Makefile
Normal file
8
doc/top/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
# $Header$
|
||||
|
||||
REFER=refer
|
||||
TBL=tbl
|
||||
TARGET=-Tlp
|
||||
|
||||
../top.doc: top.n refs.top
|
||||
$(REFER) -sA+T -l4,2 -p refs.top top.n | $(TBL) > $@
|
||||
1
emtest/last
Normal file
1
emtest/last
Normal file
@ -0,0 +1 @@
|
||||
0
|
||||
28
emtest/test.e
Normal file
28
emtest/test.e
Normal file
@ -0,0 +1,28 @@
|
||||
#define WS EM_WSIZE
|
||||
#define PS EM_PSIZE
|
||||
#include "test.h"
|
||||
mes 2,WS,PS
|
||||
mes 1
|
||||
mes 4,300
|
||||
.000
|
||||
con "tst000"
|
||||
exp $m_a_i_n
|
||||
pro $m_a_i_n,0
|
||||
loc 123
|
||||
loc -98
|
||||
; TEST 000: empty
|
||||
fil .000
|
||||
loc -98
|
||||
bne *1
|
||||
loc 123
|
||||
bne *1
|
||||
lin 0
|
||||
nop
|
||||
loc 0
|
||||
ret WS
|
||||
1
|
||||
lin 1
|
||||
nop
|
||||
loc 1
|
||||
ret WS
|
||||
end
|
||||
@ -1,24 +1,21 @@
|
||||
#!/bin/sh
|
||||
h=${1-.}
|
||||
d=${2-.}
|
||||
|
||||
em_table=$1
|
||||
h=${2-.}
|
||||
d=${3-.}
|
||||
|
||||
set `grep fpseu $em_table`
|
||||
set `grep fpseu em_table`
|
||||
p=$2
|
||||
set `grep fmnem $em_table`
|
||||
set `grep fmnem em_table`
|
||||
m=$2
|
||||
|
||||
ed - $em_table <<'A' > X
|
||||
ed - em_table <<'A' > X
|
||||
1,/^$/g/ /s// /gp
|
||||
A
|
||||
|
||||
ed - $em_table <<'A' | awk '{$2=$2+'$p'; print}' > Y
|
||||
ed - em_table <<'A' | awk '{$2=$2+'$p'; print}' > Y
|
||||
1,/^$/d
|
||||
1,/^$/g/ /s// /gp
|
||||
A
|
||||
|
||||
ed - $em_table <<'A' | awk '{print $0,'$m'+i++}' > Z
|
||||
ed - em_table <<'A' | awk '{print $0,'$m'+i++}' > Z
|
||||
1,/^$/d
|
||||
1,/^$/d
|
||||
1,/^$/g/ /s// /gp
|
||||
289
etc/pc_errors
Normal file
289
etc/pc_errors
Normal file
@ -0,0 +1,289 @@
|
||||
non-standard feature used
|
||||
identifier '%s' declared twice
|
||||
end of file encountered
|
||||
bad line directive
|
||||
unsigned real: digit of fraction expected
|
||||
unsigned real: digit of exponent expected
|
||||
unsigned real: too many digits (>72)
|
||||
unsigned integer: too many digits (>72)
|
||||
unsigned integer: overflow (>32767)
|
||||
string constant: must not exceed one line
|
||||
string constant: at least one character expected
|
||||
string constant: double quotes not allowed (see c option)
|
||||
string constant: too long (>72 chars)
|
||||
bad character
|
||||
identifier '%s' not declared
|
||||
location counter overflow: arrays too big
|
||||
location counter overflow: arrays too big
|
||||
arraysize too big
|
||||
variable '%s' never used
|
||||
variable '%s' never assigned
|
||||
the files contained in '%s' are not closed automatically
|
||||
constant expected
|
||||
constant: only integers and reals may be signed
|
||||
constant: out of bounds
|
||||
simple type expected
|
||||
enumerated type: element identifier expected
|
||||
enumerated type: ',' or ')' expected
|
||||
enumerated type: ',' expected
|
||||
enumerated type: ')' expected
|
||||
subrange type: type must be scalar, but not real
|
||||
subrange type: '..' expected
|
||||
subrange type: type of lower and upper bound incompatible
|
||||
subrange type: lower bound exceeds upper bound
|
||||
array type: '[' expected
|
||||
conformant array: low bound identifier expected
|
||||
conformant array: '..' expected
|
||||
conformant array: high bound identifier expected
|
||||
conformant array: ':' expected
|
||||
conformant array: index type identifier expected
|
||||
array type: index type not bounded
|
||||
array type: index separator or ']' expected
|
||||
array type: index separator expected
|
||||
array type: ']' expected
|
||||
array type: 'of' expected
|
||||
record variant part: tag type identifier expected
|
||||
record variant part: tag type identifier expected
|
||||
record variant part: type must be bounded
|
||||
record variant part: 'of' expected
|
||||
record variant: type of case label and tag incompatible
|
||||
record variant: multiple defined case label
|
||||
record variant: ',' or ':' expected
|
||||
record variant: ',' expected
|
||||
record variant: ':' expected
|
||||
record variant: '(' expected
|
||||
record variant: ')' expected
|
||||
record variant part: ';' or end of variant list expected
|
||||
record variant part: ';' expected
|
||||
record variant part: end of variant list expected
|
||||
record variant part: there must be a variant for each tag value
|
||||
field list: record section expected
|
||||
record section: field identifier expected
|
||||
record section: ',' or ':' expected
|
||||
record section: ',' expected
|
||||
record section: ':' expected
|
||||
field list: ';' or end of record section list expected
|
||||
field list: ';' expected
|
||||
field list: end of record section list expected
|
||||
type expected
|
||||
type: simple and pointer type may not be packed
|
||||
pointer type: type identifier expected
|
||||
pointer type: type identifier expected
|
||||
record type: 'end' expected
|
||||
set type: 'of' expected
|
||||
set type: too many elements in set
|
||||
set type: bad subrange of integer
|
||||
set of integer: the i option dictates the number of bits (default 16)
|
||||
set type: base type not bounded
|
||||
file type: 'of' expected
|
||||
file type: files within files not allowed
|
||||
var parameter: type identifier or conformant array expected
|
||||
var parameter: type identifier expected
|
||||
label declaration: unsigned integer expected
|
||||
label declaration: label '%i' multiple declared
|
||||
label declaration: ',' or ';' expected
|
||||
label declaration: ',' expected
|
||||
label declaration: ';' expected
|
||||
const declaration: constant identifier expected
|
||||
const declaration: '=' expected
|
||||
const declaration: ';' expected
|
||||
const declaration: constant identifier or 'type', 'var', 'procedure', 'function' or 'begin' expected
|
||||
type declaration: type identifier expected
|
||||
type declaration: '=' expected
|
||||
type declaration: ';' expected
|
||||
type declaration: type identifier or 'var', 'procedure', 'function' or 'begin' expected
|
||||
var declaration: var identifier expected
|
||||
var declaration: ',' or ':' expected
|
||||
var declaration: ',' expected
|
||||
var declaration: ':' expected
|
||||
var declaration: ';' expected
|
||||
var declaration: var identifier or 'procedure', 'function' or 'begin' expected
|
||||
parameter list: 'var','procedure','function' or identifier expected
|
||||
parameter list: parameter identifier expected
|
||||
parameter list: ',' or ':' expected
|
||||
parameter list: ',' expected
|
||||
parameter list: ':' expected
|
||||
parameter list: type identifier expected
|
||||
parameter list: ';' or ')' expected
|
||||
parameter list: ';' expected
|
||||
proc/func declaration: proc/func identifier expected
|
||||
proc/func declaration: previous declaration of '%s' was not forward
|
||||
proc/func declaration: parameter list expected
|
||||
parameterlist: ')' expected
|
||||
func declaration: ':' expected
|
||||
func declaration: result type identifier expected
|
||||
func declaration: result type must be scalar, subrange or pointer
|
||||
proc/func declaration: ';' expected
|
||||
proc/func declaration: block or directive expected
|
||||
proc/func declaration: '%s' unknown directive
|
||||
proc/func declaration: '%s' again forward declared
|
||||
proc/func declaration: ';' expected
|
||||
indexed variable: '[' only allowed following array variables
|
||||
indexed variable: index type not compatible with declaration
|
||||
indexed variable: ',' or ']' expected
|
||||
indexed variable: ',' expected
|
||||
assignment: standard function not allowed as destination
|
||||
assignment: cannot store the function result
|
||||
assignment: formal parameter function not allowed as destination
|
||||
assignment: function identifier may not be de-referenced
|
||||
variable: '[', '.', '^' or end of variable expected
|
||||
indexed variable: ']' expected
|
||||
field designator: field identifier expected
|
||||
field designator: '.' only allowed following record variables
|
||||
field designator: no field '%s' in this record
|
||||
referenced variable: '^' not allowed following zero-terminated strings
|
||||
referenced variable: '^' only allowed following pointer or file variables
|
||||
variable: var or field identifier expected
|
||||
call: too many actual parameters supplied
|
||||
call: proc/func identifier expected
|
||||
call: standard proc/func may not be used as parameter
|
||||
call: parameter lists of actual and formal proc/func incompatible
|
||||
call: type of actual and formal value parameter not compatible
|
||||
call: array parameter not conformable
|
||||
call: type of actual and formal variable parameter not similar
|
||||
call: packed elements not allowed as variable parameter
|
||||
call: ',' or ')' expected
|
||||
call: too few actual parameters supplied
|
||||
read(ln): type must be integer, char or real
|
||||
write(ln): type must be integer, char, real, string or boolean
|
||||
write(ln): ':', ',' or ')' expected
|
||||
write(ln): field width must be integer
|
||||
write(ln): ':', ',' or ')' expected
|
||||
write(ln): precision must be integer
|
||||
write(ln): precision may only be specified for reals
|
||||
read/write: too few actual parameters supplied
|
||||
read/write: standard input/output not mentioned in program heading
|
||||
read/write: ',' or ')' expected
|
||||
read/write: type of parameter not the same as that of the file elements
|
||||
read/write: parameter list expected
|
||||
readln/writeln: standard input/output not mentioned in program heading
|
||||
readln/writeln: only allowed on text files
|
||||
new/dispose: C-type strings not allowed here
|
||||
new/dispose: ',' or ')' expected
|
||||
new/dispose: too many actual parameters supplied
|
||||
new/dispose: type of tagfield value is incompatible with declaration
|
||||
call: '(' or end of call expected
|
||||
standard proc/func: parameter list expected
|
||||
standard input/output not mentioned in program heading
|
||||
file variable expected
|
||||
pointer variable expected
|
||||
pack: ',' expected
|
||||
pack: ',' expected
|
||||
unpack: ',' expected
|
||||
unpack: ',' expected
|
||||
standard proc/func: parameter type incompatible with specification
|
||||
eoln/page: text file variable expected
|
||||
pack/unpack: array types are incompatible
|
||||
pack/unpack: only for arrays
|
||||
abs: integer or real expected
|
||||
sqr: integer or real expected
|
||||
ord: type must be scalar or subrange, but not real
|
||||
pred/succ: type must be scalar or subrange, but not real
|
||||
trunc/round: real argument required
|
||||
call: ')' expected
|
||||
expression: left and right operand are incompatible
|
||||
set: incompatible elements
|
||||
set: base type must be bounded or of type integer
|
||||
set: base type upper bound exceeds maximum set element number
|
||||
set: element out of range
|
||||
set: ']' or element list expected
|
||||
set: '..', ',' or ']' expected
|
||||
set: ',' or ']' expected
|
||||
set: ',' expected
|
||||
factor expected
|
||||
factor: ')' expected
|
||||
factor: type of factor must be boolean
|
||||
set: ']' expected
|
||||
term: multiplying operator or end of term expected
|
||||
term: '*' only defined for integers, reals and sets
|
||||
term: '/' only defined for integers and reals
|
||||
term: 'div' only defined for integers
|
||||
term: 'mod' only defined for integers
|
||||
term: 'and' only defined for booleans
|
||||
simple expression: only integers and reals may be signed
|
||||
simple expression: adding operator or end of simple expression expected
|
||||
simple expression: '+' only defined for integers, reals and sets
|
||||
simple expression: '-' only defined for integers, reals and sets
|
||||
simple expression: 'or' only defined for booleans
|
||||
expression: relational operator or end of expression expected
|
||||
expression: set expected
|
||||
expression: left operand of 'in' not compatible with base type of right operand
|
||||
expression: only '=' and '<>' allowed on pointers
|
||||
expression: '<' and '>' not allowed on sets
|
||||
expression: comparison of arrays only allowed for strings
|
||||
expression: comparison of records not allowed
|
||||
expression: comparison of files not allowed
|
||||
assignment: ':=' expected
|
||||
assignment: left and right hand side incompatible
|
||||
goto statement: unsigned integer expected
|
||||
goto statement: label '%i' not declared
|
||||
if statement: type of expression must be boolean
|
||||
if statement: 'then' expected
|
||||
if statement: 'else' or end of if statement expected
|
||||
case statement: type must be scalar or subrange, but not real
|
||||
case statement: 'of' expected
|
||||
case statement: incompatible case label
|
||||
case statement: multiple defined case label
|
||||
case statement: ',' or ':' expected
|
||||
case statement: ',' expected
|
||||
case statement: ':' expected
|
||||
case statement: ';' or 'end' expected
|
||||
case statement: ';' expected
|
||||
case statement: 'end' expected
|
||||
repeat statement: ';' or 'until' expected
|
||||
repeat statement: ';' expected
|
||||
repeat statement: 'until' expected
|
||||
repeat statement: type of expression must be boolean
|
||||
while statement: type of expression must be boolean
|
||||
while statement: 'do' expected
|
||||
for statement: type of bound and control variable incompatible
|
||||
for statement: control variable expected
|
||||
for statement: control variable must be local
|
||||
for statement: type must be scalar or subrange, but not real
|
||||
for statement: ':=' expected
|
||||
for statement: 'to' or 'downto' expected
|
||||
for statement: upper bound not assignment compatible
|
||||
for statement: 'do' expected
|
||||
with statement: record variable expected
|
||||
with statement: ',' or 'do' expected
|
||||
with statement: ',' expected
|
||||
with statement: 'do' expected
|
||||
assertion: type of expression must be boolean
|
||||
statement expected
|
||||
label '%i' not declared
|
||||
label '%i' multiple defined
|
||||
statement: ':' expected
|
||||
unlabeled statement expected
|
||||
compound statement: ';' or 'end' expected
|
||||
compound statement: ';' expected
|
||||
compound statement: 'end' expected
|
||||
case statement: 'end' expected
|
||||
body: ';' or 'end' expected
|
||||
body: ';' expected
|
||||
body: label '%i' declared, but never defined
|
||||
program parameter '%s' not declared
|
||||
function '%s' never assigned
|
||||
block: declaration or body expected
|
||||
block: 'const', 'type', 'var', 'procedure', 'function' or 'begin' expected
|
||||
block: 'type', 'var', 'procedure', 'function' or 'begin' expected
|
||||
block: 'var', 'procedure', 'function' or 'begin' expected
|
||||
block: 'procedure', 'function' or 'begin' expected
|
||||
block: unsatisfied forward proc/func declaration(s)
|
||||
block: 'begin' expected
|
||||
block: 'end' expected
|
||||
program heading: 'program' expected
|
||||
program heading: program identifier expected
|
||||
program heading: file identifier list expected
|
||||
program heading: file identifier expected
|
||||
program heading: ',' or ')' expected
|
||||
program heading: ',' expected
|
||||
program heading: maximum number of file arguments exceeded (12)
|
||||
program heading: ')' expected
|
||||
program heading: ';' expected
|
||||
program: '.' expected
|
||||
'program' expected
|
||||
module: 'const', 'type', 'var', 'procedure' or 'function' expected
|
||||
module: 'type', 'var', 'procedure' or 'function' expected
|
||||
module: 'var', 'procedure' or 'function' expected
|
||||
module: 'procedure' or 'function' expected
|
||||
garbage at end of program
|
||||
107
etc/pc_rt_errors
Normal file
107
etc/pc_rt_errors
Normal file
@ -0,0 +1,107 @@
|
||||
array bound error
|
||||
range bound error
|
||||
set bound error
|
||||
integer overflow
|
||||
real overflow
|
||||
real underflow
|
||||
divide by 0
|
||||
divide by 0.0
|
||||
undefined integer
|
||||
real undefined
|
||||
conversion error
|
||||
error 11
|
||||
error 12
|
||||
error 13
|
||||
error 14
|
||||
error 15
|
||||
stack overflow
|
||||
heap error
|
||||
illegal instruction
|
||||
odd or zero byte count
|
||||
case error
|
||||
memory fault
|
||||
bad pointer
|
||||
bad program counter
|
||||
bad external address
|
||||
bad monitor call
|
||||
bad line number
|
||||
error 27
|
||||
error 28
|
||||
error 29
|
||||
error 30
|
||||
error 31
|
||||
error 32
|
||||
error 33
|
||||
error 34
|
||||
error 35
|
||||
error 36
|
||||
error 37
|
||||
error 38
|
||||
error 39
|
||||
error 40
|
||||
error 41
|
||||
error 42
|
||||
error 43
|
||||
error 44
|
||||
error 45
|
||||
error 46
|
||||
error 47
|
||||
error 48
|
||||
error 49
|
||||
error 50
|
||||
error 51
|
||||
error 52
|
||||
error 53
|
||||
error 54
|
||||
error 55
|
||||
error 56
|
||||
error 57
|
||||
error 58
|
||||
error 59
|
||||
error 60
|
||||
error 61
|
||||
error 62
|
||||
error 63
|
||||
more args expected
|
||||
error in exp
|
||||
error in ln
|
||||
error in sqrt
|
||||
assertion failed
|
||||
array bound error in pack
|
||||
array bound error in unpack
|
||||
only positive j in 'i mod j'
|
||||
file not yet open
|
||||
dispose error
|
||||
error 74
|
||||
error 75
|
||||
error 76
|
||||
error 77
|
||||
error 78
|
||||
error 79
|
||||
error 80
|
||||
error 81
|
||||
error 82
|
||||
error 83
|
||||
error 84
|
||||
error 85
|
||||
error 86
|
||||
error 87
|
||||
error 88
|
||||
error 89
|
||||
error 90
|
||||
error 91
|
||||
error 92
|
||||
error 93
|
||||
error 94
|
||||
error 95
|
||||
not writable
|
||||
not readable
|
||||
end of file
|
||||
truncated
|
||||
reset error
|
||||
rewrite error
|
||||
close error
|
||||
read error
|
||||
write error
|
||||
digit expected
|
||||
non-ASCII char read
|
||||
@ -1,10 +0,0 @@
|
||||
hilo.b
|
||||
hilo.c
|
||||
hilo.mod
|
||||
hilo.ocm
|
||||
hilo.p
|
||||
mandelbrot.c
|
||||
paranoia.c
|
||||
startrek.c
|
||||
startrek.doc
|
||||
README
|
||||
@ -1,33 +0,0 @@
|
||||
# $Source$
|
||||
# $State$
|
||||
# $Revision$
|
||||
|
||||
A few notes on the examples
|
||||
---------------------------
|
||||
|
||||
This directory contains a handful of working example programs that can be
|
||||
built with the ACK. They're intended as a convenient source of test code
|
||||
and as a starting point when writing your own programs.
|
||||
|
||||
They consist of:
|
||||
|
||||
hilo.c ANSI C version of the Hi/Lo game
|
||||
hilo.b Basic version of the Hi/Lo game
|
||||
hilo.mod Modula-2 version of the Hi/Lo game
|
||||
hilo.ocm Occam 1 version of the Hi/Lo game
|
||||
hilo.p Pascal version of the Hi/Lo game
|
||||
|
||||
mandelbrot.c A simple Mandelbrot generator, using floating-point maths
|
||||
paranoia.c An ancient public domain K&R C adventure game
|
||||
startrek.c An even more ancient public domain ANSI C game
|
||||
(uses the FPU for distance calculation)
|
||||
startrek.doc Manual for above (plus in current directory when running)
|
||||
|
||||
Enjoy.
|
||||
|
||||
(startrek.c was written by David Ahl and converted to C by Chris Nystrom. See
|
||||
http://www.cactus.org/%7Enystrom/startrek.html for more info.)
|
||||
|
||||
David Given
|
||||
dg@cowlark.com
|
||||
2007-02-25
|
||||
@ -1,39 +0,0 @@
|
||||
1 ' $Source$
|
||||
2 ' $State$
|
||||
3 ' $Revision$
|
||||
|
||||
10 print "Hi there! I'm written in Basic. Before we start, what is your name?"
|
||||
20 input "> ", PlayerName$
|
||||
30 print
|
||||
40 print "Hello, "; PlayerName$; "!"
|
||||
|
||||
100 gosub 1000
|
||||
110 print
|
||||
120 print "Would you like another go?"
|
||||
130 input "> ", s$
|
||||
140 s$ = left$(s$, 1)
|
||||
150 if s$ = "n" or s$ = "N" then goto 200
|
||||
160 print
|
||||
170 print "Excellent! ";
|
||||
180 goto 100
|
||||
200 print
|
||||
210 print "Thanks for playing --- goodbye!"
|
||||
220 end
|
||||
|
||||
1000 print "See if you can guess my number."
|
||||
1010 Number% = rnd(1) mod 100
|
||||
1020 Attempts% = 1
|
||||
|
||||
1030 print
|
||||
1040 input "> ", guess%
|
||||
1050 if guess% < Number% then print: print "Try a bit higher."
|
||||
1060 if guess% > Number% then print: print "Try a bit lower."
|
||||
1070 if guess% = Number% then goto 1100
|
||||
1080 Attempts% = Attempts% + 1
|
||||
1090 goto 1030
|
||||
1100 print
|
||||
1110 print "You got it right in only"; Attempts%;
|
||||
1120 if Attempts% = 1 then print "go"; else print "goes";
|
||||
1130 print "!"
|
||||
1140 return
|
||||
|
||||
@ -1,83 +0,0 @@
|
||||
/* $Source$
|
||||
* $State$
|
||||
* $Revision$
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
char buffer[32];
|
||||
char PlayerName[32];
|
||||
|
||||
int Number;
|
||||
int Attempts;
|
||||
|
||||
void reads(void)
|
||||
{
|
||||
char* p;
|
||||
|
||||
printf("> ");
|
||||
fflush(stdout);
|
||||
|
||||
fgets(buffer, sizeof(buffer), stdin);
|
||||
|
||||
p = strchr(buffer, '\n');
|
||||
if (p != NULL)
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
void game(void)
|
||||
{
|
||||
printf("See if you can guess my number.\n");
|
||||
|
||||
Number = rand() % 100;
|
||||
Attempts = 1;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int guess;
|
||||
|
||||
printf("\n");
|
||||
reads();
|
||||
guess = atoi(buffer);
|
||||
|
||||
if (guess == Number)
|
||||
{
|
||||
printf("\nYou got it right in only %d %s!\n", Attempts,
|
||||
(Attempts == 1) ? "go" : "goes");
|
||||
return;
|
||||
}
|
||||
|
||||
if (guess < Number)
|
||||
printf("\nTry a bit higher.\n");
|
||||
if (guess > Number)
|
||||
printf("\nTry a bit lower.\n");
|
||||
Attempts++;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
printf("\nHi there! I'm written in C. Before we start, what is your name?\n");
|
||||
reads();
|
||||
strcpy(PlayerName, buffer);
|
||||
printf("\nHello, %s! ", PlayerName);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
game();
|
||||
printf("\nWould you like another go?\n");
|
||||
reads();
|
||||
|
||||
if ((buffer[0] == 'n') || (buffer[0] == 'N'))
|
||||
{
|
||||
printf("\nThanks for playing --- goodbye!\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
printf("\nExcellent! ");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1,104 +0,0 @@
|
||||
(* $Source$
|
||||
* $State$
|
||||
* $Revision$
|
||||
*)
|
||||
|
||||
MODULE HiLo;
|
||||
FROM InOut IMPORT WriteInt, WriteLn, WriteString, ReadString, ReadInt;
|
||||
FROM random IMPORT Uniform;
|
||||
FROM Streams IMPORT FlushStream, OutputStream, StreamResult;
|
||||
|
||||
VAR
|
||||
buffer : ARRAY [0..32] OF CHAR;
|
||||
|
||||
PROCEDURE flush;
|
||||
VAR
|
||||
strus : StreamResult;
|
||||
BEGIN
|
||||
FlushStream(OutputStream, strus);
|
||||
END flush;
|
||||
|
||||
PROCEDURE reads;
|
||||
BEGIN
|
||||
WriteString("> ");
|
||||
flush;
|
||||
ReadString(buffer);
|
||||
END reads;
|
||||
|
||||
PROCEDURE game;
|
||||
VAR
|
||||
Number : INTEGER;
|
||||
Attempts : INTEGER;
|
||||
guess : INTEGER;
|
||||
finished : BOOLEAN;
|
||||
BEGIN
|
||||
WriteString("See if you can guess my number.");
|
||||
WriteLn;
|
||||
|
||||
Number := Uniform(0, 99);
|
||||
Attempts := 1;
|
||||
finished := FALSE;
|
||||
|
||||
WHILE NOT finished DO
|
||||
WriteString("> ");
|
||||
flush;
|
||||
ReadInt(guess);
|
||||
|
||||
IF guess = Number THEN
|
||||
WriteLn;
|
||||
WriteString("You got it right in only ");
|
||||
WriteInt(Attempts, 0);
|
||||
WriteString(" ");
|
||||
IF Attempts = 1 THEN
|
||||
WriteString("go");
|
||||
ELSE
|
||||
WriteString("goes");
|
||||
END;
|
||||
WriteString("!");
|
||||
WriteLn;
|
||||
finished := TRUE;
|
||||
ELSIF guess < Number THEN
|
||||
WriteLn;
|
||||
WriteString("Try a bit higher.");
|
||||
WriteLn;
|
||||
ELSIF guess > Number THEN
|
||||
WriteLn;
|
||||
WriteString("Try a bit lower.");
|
||||
WriteLn;
|
||||
END;
|
||||
|
||||
Attempts := Attempts + 1;
|
||||
END;
|
||||
END game;
|
||||
|
||||
VAR
|
||||
finished : BOOLEAN;
|
||||
BEGIN
|
||||
WriteLn;
|
||||
WriteString("Hi there! I'm written in Modula-2. Before we start, what is your name?");
|
||||
WriteLn;
|
||||
reads;
|
||||
WriteLn;
|
||||
WriteString("Hello, ");
|
||||
WriteString(buffer);
|
||||
WriteString("! ");
|
||||
|
||||
finished := FALSE;
|
||||
WHILE NOT finished DO
|
||||
game;
|
||||
WriteLn;
|
||||
WriteString("Would you like another go?");
|
||||
WriteLn;
|
||||
reads;
|
||||
|
||||
IF (buffer[0] = 'n') OR (buffer[0] = 'N') THEN
|
||||
finished := TRUE;
|
||||
WriteLn;
|
||||
WriteString("Thanks for playing --- goodbye!");
|
||||
WriteLn;
|
||||
ELSE
|
||||
WriteLn;
|
||||
WriteString("Excellent! ");
|
||||
END;
|
||||
END;
|
||||
END HiLo.
|
||||
@ -1,131 +0,0 @@
|
||||
#
|
||||
-- $Source$
|
||||
-- $State$
|
||||
-- $Revision$
|
||||
|
||||
#include "dec.ocm"
|
||||
|
||||
-- General utilities: read and write strings.
|
||||
|
||||
proc puts(value s[]) =
|
||||
seq i = [1 for s[byte 0]]
|
||||
output ! s[byte i]
|
||||
:
|
||||
|
||||
proc gets(var s[]) =
|
||||
var length, finished, c:
|
||||
seq
|
||||
finished := false
|
||||
length := 0
|
||||
|
||||
while not finished
|
||||
seq
|
||||
input ? c
|
||||
if
|
||||
c = 10
|
||||
finished := true
|
||||
true
|
||||
seq
|
||||
length := length + 1
|
||||
s[byte length] := c
|
||||
|
||||
s[byte 0] := length
|
||||
:
|
||||
|
||||
-- Our random number generator.
|
||||
|
||||
var seed:
|
||||
proc randomise(value s) =
|
||||
seq
|
||||
seed := s
|
||||
:
|
||||
|
||||
proc random(value range, var result) =
|
||||
seq
|
||||
seed := (20077 * seed) + 12345
|
||||
if
|
||||
seed < 0
|
||||
seed := -seed
|
||||
true
|
||||
skip
|
||||
result := seed \ range
|
||||
:
|
||||
|
||||
-- Does the reading-in-the-name thing.
|
||||
|
||||
proc getname =
|
||||
var seed, buffer[128]:
|
||||
seq
|
||||
puts("*nHi there! I'm written in Occam. Before we start, what is your name?*n")
|
||||
puts("> ")
|
||||
gets(buffer)
|
||||
|
||||
seed := 0
|
||||
seq i = [1 for buffer[byte 0]]
|
||||
seed := seed + buffer[byte i]
|
||||
randomise(seed)
|
||||
|
||||
puts("*nHello, ")
|
||||
puts(buffer)
|
||||
puts("! ")
|
||||
:
|
||||
|
||||
-- Plays a single game.
|
||||
|
||||
proc game =
|
||||
var Number, Attempts, finished, guess:
|
||||
seq
|
||||
puts("See if you can guess my number.*n")
|
||||
random(100, Number)
|
||||
Attempts := 1
|
||||
finished := false
|
||||
while not finished
|
||||
seq
|
||||
puts("*n> ")
|
||||
var c:
|
||||
seq
|
||||
c := '*s'
|
||||
decin(input, guess, c)
|
||||
|
||||
if
|
||||
guess = Number
|
||||
seq
|
||||
puts("*nYou got it right in only ")
|
||||
decout(output, Attempts, 0)
|
||||
puts(" ")
|
||||
if
|
||||
Attempts = 1
|
||||
puts("go")
|
||||
true
|
||||
puts("goes")
|
||||
puts("!*n")
|
||||
finished := true
|
||||
|
||||
guess < Number
|
||||
puts("*nTry a bit higher.*n")
|
||||
guess > Number
|
||||
puts("*nTry a bit lower.*n")
|
||||
Attempts := Attempts + 1
|
||||
:
|
||||
|
||||
var finished, buffer[128]:
|
||||
seq
|
||||
output ! TEXT
|
||||
getname
|
||||
|
||||
finished := false
|
||||
while not finished
|
||||
seq
|
||||
game
|
||||
|
||||
puts("*nWould you like another go?*n")
|
||||
puts("> ")
|
||||
gets(buffer)
|
||||
if
|
||||
(buffer[byte 1] = 'n') or (buffer[byte 1] = 'N')
|
||||
seq
|
||||
finished := true
|
||||
puts("*nThanks for playing --- goodbye!*n")
|
||||
true
|
||||
puts("*nExcellent! ")
|
||||
|
||||
169
examples/hilo.p
169
examples/hilo.p
@ -1,169 +0,0 @@
|
||||
(* $Source$
|
||||
* $State$
|
||||
* $Revision$
|
||||
*)
|
||||
|
||||
(*$U+ --- enables underscores in identifiers *)
|
||||
|
||||
program hilo(input, output);
|
||||
|
||||
type
|
||||
string = array [0..255] of char;
|
||||
|
||||
var
|
||||
playing : Boolean;
|
||||
seed : integer;
|
||||
|
||||
{ This version of Pascal seems to have no random number generator I can find,
|
||||
so we have to implement our own here. This is a hacked up and probably
|
||||
broken version of the C library generator. }
|
||||
|
||||
procedure randomise(s : integer);
|
||||
begin
|
||||
seed := s;
|
||||
end;
|
||||
|
||||
function random(range : integer) : integer;
|
||||
begin
|
||||
seed := (20077 * seed + 12345);
|
||||
random := seed mod range;
|
||||
end;
|
||||
|
||||
{ Pascal doesn't provide string input, so we interface to the read() syscall
|
||||
and do it manually. But... we can't interface to read() directly because
|
||||
that conflicts with a Pascal keyword. Luckily there's a private function
|
||||
uread() in the ACK Pascal library that we can use instead. }
|
||||
|
||||
function uread(fd : integer; var buffer : char; count : integer) : integer;
|
||||
extern;
|
||||
|
||||
function readchar : char;
|
||||
var
|
||||
c : char;
|
||||
dummy : integer;
|
||||
|
||||
begin
|
||||
c := chr(0);
|
||||
dummy := uread(0, c, 1);
|
||||
readchar := c;
|
||||
end;
|
||||
|
||||
procedure readstring(var buffer : string; var length : integer);
|
||||
var
|
||||
finished : Boolean;
|
||||
c : char;
|
||||
|
||||
begin
|
||||
write('> ');
|
||||
|
||||
length := 0;
|
||||
finished := FALSE;
|
||||
seed := 0;
|
||||
while not finished do
|
||||
begin
|
||||
c := readchar;
|
||||
if (ord(c) = 10) then
|
||||
finished := true
|
||||
else
|
||||
begin
|
||||
buffer[length] := c;
|
||||
length := length + 1;
|
||||
end
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure getname;
|
||||
var
|
||||
name : string;
|
||||
namelen : integer;
|
||||
i : integer;
|
||||
seed : integer;
|
||||
|
||||
begin
|
||||
writeln;
|
||||
writeln('Hi there! I''m written in Pascal. Before we start, what is your name?');
|
||||
writeln;
|
||||
readstring(name, namelen);
|
||||
writeln;
|
||||
write('Hello, ');
|
||||
|
||||
seed := 0;
|
||||
for i := 0 to (namelen-1) do
|
||||
begin
|
||||
write(name[i]);
|
||||
seed := seed + ord(name[i]);
|
||||
end;
|
||||
|
||||
randomise(seed);
|
||||
write('! ');
|
||||
end;
|
||||
|
||||
procedure game;
|
||||
var
|
||||
Number : integer;
|
||||
Attempts : integer;
|
||||
guess : integer;
|
||||
|
||||
begin
|
||||
writeln('See if you can guess my number.');
|
||||
Number := random(100);
|
||||
Attempts := 0;
|
||||
|
||||
guess := -1;
|
||||
while guess <> Number do
|
||||
begin
|
||||
Attempts := Attempts + 1;
|
||||
write('> ');
|
||||
readln(guess);
|
||||
|
||||
if guess < Number then
|
||||
begin
|
||||
writeln;
|
||||
writeln('Try a bit higher.');
|
||||
end;
|
||||
|
||||
if guess > Number then
|
||||
begin
|
||||
writeln;
|
||||
writeln('Try a bit lower.');
|
||||
end;
|
||||
end;
|
||||
|
||||
writeln;
|
||||
write('You got it right in only ', Attempts:0, ' ');
|
||||
if Attempts = 1 then
|
||||
write('go')
|
||||
else
|
||||
write('goes');
|
||||
writeln('!');
|
||||
end;
|
||||
|
||||
function question: Boolean;
|
||||
var
|
||||
response: char;
|
||||
|
||||
begin
|
||||
write('> ');
|
||||
readln(response);
|
||||
|
||||
question := not ((response = 'n') or (response = 'N'));
|
||||
end;
|
||||
|
||||
begin
|
||||
getname;
|
||||
|
||||
playing := TRUE;
|
||||
while playing do
|
||||
begin
|
||||
game;
|
||||
writeln;
|
||||
writeln('Would you like another go?');
|
||||
playing := question;
|
||||
|
||||
writeln;
|
||||
if playing then
|
||||
write('Excellent! ')
|
||||
else
|
||||
writeln('Thanks for playing --- goodbye!');
|
||||
end;
|
||||
end.
|
||||
@ -1,73 +0,0 @@
|
||||
/* $Source$
|
||||
* $State$
|
||||
* $Revision$
|
||||
*/
|
||||
|
||||
/* Adapted from code by Chris Losinger. (This is the non-obfuscated
|
||||
* version...
|
||||
*
|
||||
* http://www.codeproject.com/cpp/mandelbrot_obfuscation.asp
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
enum
|
||||
{
|
||||
ROWS = 40,
|
||||
COLUMNS = 60,
|
||||
|
||||
MAX_ITERATIONS = 255
|
||||
};
|
||||
|
||||
void nl(void)
|
||||
{
|
||||
write(1, "\n", 1);
|
||||
}
|
||||
|
||||
void out(int n)
|
||||
{
|
||||
const char* chars = "****++++++---- ";
|
||||
write(1, chars + (n/16), 1);
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
/* Size and position of the visible area. */
|
||||
|
||||
double view_r = -2.3, view_i = -1.0;
|
||||
double zoom = 0.05;
|
||||
int x, y, n;
|
||||
|
||||
for (y=0; y < ROWS; y++)
|
||||
{
|
||||
double c_i = view_i + y * zoom;
|
||||
|
||||
for (x=0; x < COLUMNS; x++)
|
||||
{
|
||||
double c_r = view_r + x*zoom;
|
||||
double z_r = c_r;
|
||||
double z_i = c_i;
|
||||
|
||||
for (n=0; n < MAX_ITERATIONS; n++)
|
||||
{
|
||||
double z_r2 = z_r * z_r;
|
||||
double z_i2 = z_i * z_i;
|
||||
|
||||
/* Have we escaped? */
|
||||
|
||||
if (z_r2 + z_i2 > 4)
|
||||
break;
|
||||
|
||||
/* z = z^2 + c */
|
||||
z_i = 2 * z_r * z_i + c_i;
|
||||
z_r = z_r2 - z_i2 + c_r;
|
||||
}
|
||||
|
||||
out(n);
|
||||
}
|
||||
nl();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
1047
examples/paranoia.c
1047
examples/paranoia.c
File diff suppressed because it is too large
Load Diff
1962
examples/startrek.c
1962
examples/startrek.c
File diff suppressed because it is too large
Load Diff
@ -1,105 +0,0 @@
|
||||
|
||||
1. When you see _Command?_ printed, enter one of the legal commands
|
||||
(nav, srs, lrs, pha, tor, she, dam, com, or xxx).
|
||||
|
||||
2. If you should type in an illegal command, you'll get a short list of
|
||||
the legal commands printed out.
|
||||
|
||||
3. Some commands require you to enter data (for example, the 'nav' command
|
||||
comes back with 'Course(1-9) ?'.) If you type in illegal data (like
|
||||
negative numbers), that command will be aborted.
|
||||
|
||||
The galaxy is divided into an 8 X 8 quadrant grid, and each quadrant
|
||||
is further divided into an 8 x 8 sector grid.
|
||||
|
||||
You will be assigned a starting point somewhere in the galaxy to begin
|
||||
a tour of duty as commander of the starship _Enterprise_; your mission:
|
||||
to seek out and destroy the fleet of Klingon warships which are menacing
|
||||
the United Federation of Planets.
|
||||
|
||||
You have the following commands available to you as Captain of the Starship
|
||||
Enterprise:
|
||||
|
||||
\nav\ Command = Warp Engine Control --
|
||||
|
||||
Course is in a circular numerical vector 4 3 2
|
||||
arrangement as shown. Integer and real . . .
|
||||
values may be used. (Thus course 1.5 is ...
|
||||
half-way between 1 and 2. 5 ---*--- 1
|
||||
...
|
||||
Values may approach 9.0, which itself is . . .
|
||||
equivalent to 1.0. 6 7 8
|
||||
|
||||
One warp factor is the size of one quadrant. COURSE
|
||||
Therefore, to get from quadrant 6,5 to 5,5
|
||||
you would use course 3, warp factor 1.
|
||||
|
||||
\srs\ Command = Short Range Sensor Scan
|
||||
|
||||
Shows you a scan of your present quadrant.
|
||||
|
||||
Symbology on your sensor screen is as follows:
|
||||
<*> = Your starship's position
|
||||
+K+ = Klingon battlecruiser
|
||||
>!< = Federation starbase (Refuel/Repair/Re-Arm here)
|
||||
* = Star
|
||||
|
||||
A condensed 'Status Report' will also be presented.
|
||||
|
||||
\lrs\ Command = Long Range Sensor Scan
|
||||
|
||||
Shows conditions in space for one quadrant on each side of the Enterprise
|
||||
(which is in the middle of the scan). The scan is coded in the form \###\
|
||||
where the units digit is the number of stars, the tens digit is the number
|
||||
of starbases, and the hundreds digit is the number of Klingons.
|
||||
|
||||
Example - 207 = 2 Klingons, No Starbases, & 7 stars.
|
||||
|
||||
\pha\ Command = Phaser Control.
|
||||
|
||||
Allows you to destroy the Klingon Battle Cruisers by zapping them with
|
||||
suitably large units of energy to deplete their shield power. (Remember,
|
||||
Klingons have phasers, too!)
|
||||
|
||||
\tor\ Command = Photon Torpedo Control
|
||||
|
||||
Torpedo course is the same as used in warp engine control. If you hit
|
||||
the Klingon vessel, he is destroyed and cannot fire back at you. If you
|
||||
miss, you are subject to the phaser fire of all other Klingons in the
|
||||
quadrant.
|
||||
|
||||
The Library-Computer (\com\ command) has an option to compute torpedo
|
||||
trajectory for you (option 2).
|
||||
|
||||
\she\ Command = Shield Control
|
||||
|
||||
Defines the number of energy units to be assigned to the shields. Energy
|
||||
is taken from total ship's energy. Note that the status display total
|
||||
energy includes shield energy.
|
||||
|
||||
\dam\ Command = Damage Control report
|
||||
Gives the state of repair of all devices. Where a negative 'State of Repair'
|
||||
shows that the device is temporarily damaged.
|
||||
|
||||
\com\ Command = Library-Computer
|
||||
The Library-Computer contains six options:
|
||||
Option 0 = Cumulative Galactic Record
|
||||
This option shows computer memory of the results of all previous
|
||||
short and long range sensor scans.
|
||||
Option 1 = Status Report
|
||||
This option shows the number of Klingons, stardates, and starbases
|
||||
remaining in the game.
|
||||
Option 2 = Photon Torpedo Data
|
||||
Which gives directions and distance from Enterprise to all Klingons
|
||||
in your quadrant.
|
||||
Option 3 = Starbase Nav Data
|
||||
This option gives direction and distance to any starbase in your
|
||||
quadrant.
|
||||
Option 4 = Direction/Distance Calculator
|
||||
This option allows you to enter coordinates for direction/distance
|
||||
calculations.
|
||||
Option 5 = Galactic /Region Name/ Map
|
||||
This option prints the names of the sixteen major galactic regions
|
||||
referred to in the game.
|
||||
|
||||
|
||||
42
first/.distr
42
first/.distr
@ -1,24 +1,18 @@
|
||||
ack.pm
|
||||
ack-custom.pm
|
||||
c.pm
|
||||
llgen.pm
|
||||
yacc.pm
|
||||
|
||||
#create_dir
|
||||
#cp_dir
|
||||
#em_path.h.src
|
||||
#first
|
||||
#get_answer
|
||||
#get_makepars
|
||||
#get_sys
|
||||
#get_sysvax
|
||||
#install_tail
|
||||
#limit_enquire
|
||||
#limit_impl
|
||||
#lint_params
|
||||
#local.h.src
|
||||
#mk_config
|
||||
#mk_makefile
|
||||
#mk_target
|
||||
#target_comp
|
||||
#util_comp
|
||||
create_dir
|
||||
cp_dir
|
||||
em_path.h.src
|
||||
first
|
||||
get_answer
|
||||
get_makepars
|
||||
get_sys
|
||||
get_sysvax
|
||||
install_tail
|
||||
limit_enquire
|
||||
limit_impl
|
||||
lint_params
|
||||
local.h.src
|
||||
mk_config
|
||||
mk_makefile
|
||||
mk_target
|
||||
target_comp
|
||||
util_comp
|
||||
|
||||
@ -1,21 +0,0 @@
|
||||
-- $Source$
|
||||
-- $State$
|
||||
|
||||
-- Custom rules used by the ACK build process.
|
||||
|
||||
preprocess = simple {
|
||||
class = "preprocess",
|
||||
outputs = {"%U%-%I%"},
|
||||
command = {
|
||||
"cpp -I%HEADERDIR% %in% > %out[1]%"
|
||||
}
|
||||
}
|
||||
|
||||
-- Revision history
|
||||
-- $Log$
|
||||
-- Revision 1.2 2007-02-20 00:32:58 dtrg
|
||||
-- Changed the 'preprocess' rule to use the system C preprocessor.
|
||||
--
|
||||
-- Revision 1.1 2006/07/22 00:49:48 dtrg
|
||||
-- First version in CVS.
|
||||
--
|
||||
33
first/ack.pm
33
first/ack.pm
@ -1,33 +0,0 @@
|
||||
-- $Source$
|
||||
-- $State$
|
||||
|
||||
-- Provides rules for building things with the half-built ACK itself.
|
||||
|
||||
ACKBUILDFLAGS = {"-m%PLATFORM%", "%OPTIMISATION%"}
|
||||
ACKDEFINES = EMPTY
|
||||
ACKINCLUDES = EMPTY
|
||||
|
||||
ackfile = simple_with_clike_dependencies {
|
||||
class = "ackfile",
|
||||
CINCLUDES = {REDIRECT, "ACKINCLUDES"},
|
||||
command = {
|
||||
"%BINDIR%bin/ack %ACKBUILDFLAGS% %ACKINCLUDES:cincludes% %ACKDEFINES:cdefines% -c -o %out% %in%"
|
||||
},
|
||||
outputs = {"%U%-%I%.o"},
|
||||
}
|
||||
|
||||
ackprogram = simple {
|
||||
class = "ackprogram",
|
||||
command = {
|
||||
"%BINDIR%bin/ack %ACKBUILDFLAGS% -o %out% %in%"
|
||||
},
|
||||
outputs = {"%U%-%I%"},
|
||||
}
|
||||
|
||||
acklibrary = simple {
|
||||
class = "acklibrary",
|
||||
command = {
|
||||
"%RM% %out% && %BINDIR%bin/aal cr %out% %in%"
|
||||
},
|
||||
outputs = {"%U%-%I%.a"},
|
||||
}
|
||||
238
first/c.pm
238
first/c.pm
@ -1,238 +0,0 @@
|
||||
-- $Id$
|
||||
-- $HeadURL: https://primemover.svn.sf.net/svnroot/primemover/pm/lib/c.pm $
|
||||
-- $LastChangedDate: 2007-02-24 01:37:06 +0000 (Sat, 24 Feb 2007) $
|
||||
|
||||
-- pm includefile to compile *host* C programs.
|
||||
|
||||
-- Standard Lua boilerplate.
|
||||
|
||||
local io_open = io.open
|
||||
local string_gsub = string.gsub
|
||||
local string_gfind = string.gfind
|
||||
local string_find = string.find
|
||||
local table_insert = table.insert
|
||||
local table_getn = table.getn
|
||||
local filetime = pm.filetime
|
||||
|
||||
-- Define some variables.
|
||||
|
||||
CCOMPILER = "gcc"
|
||||
CXXCOMPILER = "g++"
|
||||
CC = "%CCOMPILER% %CBUILDFLAGS% %CDYNINCLUDES:cincludes% %CINCLUDES:cincludes% %CDEFINES:cdefines% %CEXTRAFLAGS% -c -o %out% %in%"
|
||||
CXX = "%CXXCOMPILER% %CBUILDFLAGS% %CDYNINCLUDES:cincludes% %CINCLUDES:cincludes% %CDEFINES:cdefines% %CEXTRAFLAGS% -c -o %out% %in%"
|
||||
CPROGRAM = "%CCOMPILER% %CBUILDFLAGS% %CLINKFLAGS% %CEXTRAFLAGS% -o %out% %in% %CLIBRARIES:clibraries%"
|
||||
CXXPROGRAM = "%CXXCOMPILER% %CBUILDFLAGS% %CLINKFLAGS% %CEXTRAFLAGS% -o %out% %in% %CLIBRARIES:clibraries%"
|
||||
|
||||
CLIBRARY = "rm -f %out% && ar cr %out% %in% && ranlib %out%"
|
||||
|
||||
CBUILDFLAGS = {"-g"}
|
||||
CINCLUDES = EMPTY
|
||||
CDEFINES = EMPTY
|
||||
CEXTRAFLAGS = EMPTY
|
||||
CLINKFLAGS = EMPTY
|
||||
CDYNINCLUDES = EMPTY
|
||||
CLIBRARIES = EMPTY
|
||||
|
||||
--- Custom string modifiers -------------------------------------------------
|
||||
|
||||
local function prepend(rule, arg, prefix)
|
||||
if (arg == EMPTY) then
|
||||
return EMPTY
|
||||
end
|
||||
|
||||
local t = {}
|
||||
for i, j in ipairs(arg) do
|
||||
t[i] = prefix..j
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
function pm.stringmodifier.cincludes(rule, arg)
|
||||
return prepend(rule, arg, "-I")
|
||||
end
|
||||
|
||||
function pm.stringmodifier.cdefines(rule, arg)
|
||||
return prepend(rule, arg, "-D")
|
||||
end
|
||||
|
||||
function pm.stringmodifier.clibraries(rule, arg)
|
||||
if (arg == EMPTY) then
|
||||
return EMPTY
|
||||
end
|
||||
|
||||
local t = {}
|
||||
for i, j in ipairs(arg) do
|
||||
if string_find(j, "%.a$") then
|
||||
t[i] = j
|
||||
else
|
||||
t[i] = "-l"..j
|
||||
end
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
--- Manage C file dependencies ----------------------------------------------
|
||||
|
||||
local dependency_cache = {}
|
||||
local function calculate_dependencies(filename, includes)
|
||||
-- Cache values, so we don't recalculate dependencies needlessly.
|
||||
|
||||
local o = dependency_cache[filename]
|
||||
if o then
|
||||
return o
|
||||
end
|
||||
|
||||
local deps = {}
|
||||
deps[filename] = true
|
||||
|
||||
local calcdeps = 0
|
||||
calcdeps = function(filename, file)
|
||||
file = file or io_open(filename)
|
||||
if not file then
|
||||
return
|
||||
end
|
||||
|
||||
local localincludes = string_gsub(filename, "/[^/]*$", "")
|
||||
if localincludes then
|
||||
localincludes = {localincludes, unpack(includes)}
|
||||
else
|
||||
localincludes = includes
|
||||
end
|
||||
|
||||
for line in file:lines() do
|
||||
local _, _, f = string_find(line, '^[ \t]*#[ \t]*include[ \t]*["<]([^"]+)[">]')
|
||||
if f then
|
||||
for _, path in ipairs(localincludes) do
|
||||
local subfilename = path.."/"..f
|
||||
local subfile = io_open(subfilename)
|
||||
if subfile then
|
||||
if not deps[subfilename] then
|
||||
deps[subfilename] = true
|
||||
calcdeps(subfilename, subfile)
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Explicit close to avoid having to wait for the garbage collector
|
||||
-- to free up the underlying fd.
|
||||
|
||||
file:close()
|
||||
end
|
||||
|
||||
calcdeps(filename)
|
||||
o = {}
|
||||
for i, _ in pairs(deps) do
|
||||
table_insert(o, i)
|
||||
end
|
||||
|
||||
dependency_cache[filename] = o
|
||||
return o
|
||||
end
|
||||
|
||||
-- This clause specialises 'simple' to add support for smart dependencies of C
|
||||
-- files.
|
||||
|
||||
simple_with_clike_dependencies = simple {
|
||||
class = "simple_with_clike_dependencies",
|
||||
makedepends = {"%CDEPENDS%"},
|
||||
|
||||
__init = function(self, p)
|
||||
simple.__init(self, p)
|
||||
|
||||
-- If we're a class, don't verify.
|
||||
|
||||
if ((type(p) == "table") and p.class) then
|
||||
return
|
||||
end
|
||||
|
||||
-- If dynamicheaders is an object, turn it into a singleton list.
|
||||
|
||||
if self.dynamicheaders then
|
||||
if (type(self.dynamicheaders) ~= "table") then
|
||||
self:__error("doesn't know what to do with dynamicheaders, which ",
|
||||
"should be a list or an object but was a ", type(self.dynamicheaders))
|
||||
end
|
||||
if self.dynamicheaders.class then
|
||||
self.dynamicheaders = {self.dynamicheaders}
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
__dependencies = function(self, inputs, outputs)
|
||||
local cincludes = self:__index("CINCLUDES")
|
||||
if (type(cincludes) == "string") then
|
||||
cincludes = {cincludes}
|
||||
end
|
||||
|
||||
local includes = {}
|
||||
for _, i in ipairs(cincludes) do
|
||||
table_insert(includes, self:__expand(i))
|
||||
end
|
||||
|
||||
local input = self:__expand(inputs[1])
|
||||
local depends = calculate_dependencies(input, includes)
|
||||
if not depends then
|
||||
self:__error("could not determine the dependencies for ",
|
||||
pm.rendertable({input}))
|
||||
end
|
||||
if pm.verbose then
|
||||
pm.message('"', input, '" appears to depend on ',
|
||||
pm.rendertable(depends))
|
||||
end
|
||||
return depends
|
||||
end,
|
||||
|
||||
__buildadditionalchildren = function(self)
|
||||
self.CDYNINCLUDES = {}
|
||||
if self.dynamicheaders then
|
||||
for _, i in ipairs(self.dynamicheaders) do
|
||||
local o = i:__build()
|
||||
if o[1] then
|
||||
table_insert(self.CDYNINCLUDES, (string_gsub(o[1], "/[^/]*$", "")))
|
||||
end
|
||||
end
|
||||
end
|
||||
-- If no paths on the list, replace the list with EMPTY so it doesn't
|
||||
-- expand to anything.
|
||||
if (table_getn(self.CDYNINCLUDES) == 0) then
|
||||
self.CDYNINCLUDES = EMPTY
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
-- These are the publically useful clauses.
|
||||
|
||||
cfile = simple_with_clike_dependencies {
|
||||
class = "cfile",
|
||||
command = {"%CC%"},
|
||||
outputs = {"%U%-%I%.o"},
|
||||
}
|
||||
|
||||
cxxfile = simple_with_clike_dependencies {
|
||||
class = "cxxfile",
|
||||
command = {"%CXX%"},
|
||||
outputs = {"%U%-%I%.o"},
|
||||
}
|
||||
|
||||
cprogram = simple {
|
||||
class = "cprogram",
|
||||
command = {"%CPROGRAM%"},
|
||||
outputs = {"%U%-%I%"},
|
||||
}
|
||||
|
||||
cxxprogram = simple {
|
||||
class = "cxxprogram",
|
||||
command = {"%CXXPROGRAM%"},
|
||||
outputs = {"%U%-%I%"},
|
||||
}
|
||||
|
||||
clibrary = simple {
|
||||
class = "clibrary",
|
||||
command = {
|
||||
"%CLIBRARY%"
|
||||
},
|
||||
outputs = {"%U%-%I%.a"},
|
||||
}
|
||||
70
first/cc.xenix.src
Normal file
70
first/cc.xenix.src
Normal file
@ -0,0 +1,70 @@
|
||||
trap "rm -f x$$.c" 0 1 2 3 15
|
||||
EMHOME=/usr/em
|
||||
CFLAG=0
|
||||
TARGET=a.out
|
||||
while :
|
||||
do
|
||||
case $# in
|
||||
0) break;;
|
||||
esac
|
||||
case $1 in
|
||||
-I*|-D*|-U*)
|
||||
PREP=$PREP" "$1
|
||||
;;
|
||||
-c) CFLAG=1
|
||||
;;
|
||||
-o) shift
|
||||
TARGET=$1
|
||||
;;
|
||||
-F) shift
|
||||
LFLAG="-F $1"
|
||||
;;
|
||||
-*) FLAGS=$FLAGS" "$1
|
||||
;;
|
||||
*) ARG=$ARG" "$1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
for i in $ARG
|
||||
do
|
||||
case $i in
|
||||
*.c)
|
||||
nm=`basename $i .c`
|
||||
if [ -x $EMHOME/lib/cpp ]
|
||||
then
|
||||
cpp=$EMHOME/lib/cpp
|
||||
cppf=-P
|
||||
else
|
||||
cpp=/bin/cc
|
||||
cppf=-E
|
||||
fi
|
||||
if $cpp $cppf $PREP $i > x$$.c && /bin/cc $FLAGS -c x$$.c
|
||||
then
|
||||
mv x$$.o $nm.o
|
||||
LDARG=$LDARG" "$nm.o
|
||||
else
|
||||
rm -f x$$.c
|
||||
exit 1
|
||||
fi
|
||||
rm -f x$$.c
|
||||
;;
|
||||
*.s)
|
||||
if /bin/cc $FLAGS -c $i
|
||||
then
|
||||
LDARG=$LDARG" "`basename $i .s`.o
|
||||
else exit 1
|
||||
fi
|
||||
;;
|
||||
*) LDARG=$LDARG" "$i
|
||||
;;
|
||||
esac
|
||||
done
|
||||
case $CFLAG in
|
||||
1) ;;
|
||||
*) if /bin/cc $FLAGS $LFLAG $LDARG -o $TARGET
|
||||
then :
|
||||
else exit 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
67
first/ckpath
Normal file
67
first/ckpath
Normal file
@ -0,0 +1,67 @@
|
||||
rm -f ../bin/x_tpath x_tpath
|
||||
echo 'Checking out your $PATH; . and $ACK/bin should be in front ...'
|
||||
echo "echo $$" >../bin/x_tpath
|
||||
rm -f x_tpath
|
||||
chmod +x ../bin/x_tpath
|
||||
case x`(x_tpath) 2>/dev/null`
|
||||
in
|
||||
x$$)
|
||||
STAT=0 ;;
|
||||
x)
|
||||
(cd ../bin ; echo Sorry, `pwd` is not in your shell PATH" ($PATH)")
|
||||
STAT=1 ;;
|
||||
*)
|
||||
echo "Sorry, there is something wrong with your PATH ($PATH)" ;;
|
||||
esac
|
||||
echo "echo t_$$" > X_Y_Z_
|
||||
chmod +x X_Y_Z_
|
||||
case x`X_Y_Z_`
|
||||
in
|
||||
xt_$$)
|
||||
;;
|
||||
x)
|
||||
(cd ../bin ; echo Sorry, . is not in your shell PATH" ($PATH)")
|
||||
STAT=2 ;;
|
||||
*)
|
||||
echo "Sorry, there is something wrong with your PATH ($PATH)" ;;
|
||||
esac
|
||||
rm -f X_Y_Z_
|
||||
case $STAT
|
||||
in
|
||||
2)
|
||||
;;
|
||||
*)
|
||||
hash -r ;;
|
||||
esac
|
||||
echo "echo l_$$" >x_tpath
|
||||
chmod +x x_tpath
|
||||
case x`(x_tpath) 2>/dev/null`
|
||||
in
|
||||
xl_$$)
|
||||
;;
|
||||
x)
|
||||
(cd ../bin ; echo Sorry, . is not in your shell PATH" ($PATH)")
|
||||
STAT=2 ;;
|
||||
x$$)
|
||||
echo Sorry, . is not in your PATH" ($PATH)" or after the ACK bin directory
|
||||
STAT=3 ;;
|
||||
*)
|
||||
echo "Sorry, there is something wrong with your PATH ($PATH)"
|
||||
STAT=4 ;;
|
||||
esac
|
||||
rm -f ../bin/x_tpath x_tpath
|
||||
echo "echo 93" > ../bin/cat
|
||||
chmod +x ../bin/cat
|
||||
hash -r
|
||||
case x`cat < /dev/null 2>/dev/null`
|
||||
in
|
||||
x93)
|
||||
rm -f ../bin/cat
|
||||
;;
|
||||
*)
|
||||
rm -f ../bin/cat
|
||||
(cd ../bin ; echo Sorry, `pwd` comes too late in your PATH" ($PATH)" )
|
||||
STAT=13
|
||||
;;
|
||||
esac
|
||||
exit $STAT
|
||||
@ -1,5 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
trap "rm -f /tmp/xx$$" 0 1 2 3 15
|
||||
case $2 in
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
if ( cd $1 ) 2>/dev/null
|
||||
then
|
||||
:
|
||||
|
||||
7
first/did_first
Executable file
7
first/did_first
Executable file
@ -0,0 +1,7 @@
|
||||
if (ack_sys ) >/dev/null 2>&1
|
||||
then
|
||||
exit 0
|
||||
else
|
||||
echo "You need to run 'first' first"
|
||||
exit 1
|
||||
fi
|
||||
@ -1,5 +1,4 @@
|
||||
#! /bin/sh
|
||||
|
||||
case $0 in
|
||||
*/first)
|
||||
FDIR=`expr $0 : '\(.*\)/first'`
|
||||
|
||||
75
first/fixlexlib
Executable file
75
first/fixlexlib
Executable file
@ -0,0 +1,75 @@
|
||||
FL=succes
|
||||
TRIES=
|
||||
case X$# in
|
||||
X0)
|
||||
if (.Xlex) > /dev/null 2>&1
|
||||
then
|
||||
TRY=`.Xlex`
|
||||
else TRY=-lln
|
||||
fi
|
||||
echo "trying to find your lex library ..."
|
||||
cat > x.l <<'EOF'
|
||||
%%
|
||||
[A-Z] putchar(yytext[0]+'a'-'A');
|
||||
EOF
|
||||
if lex x.l > /dev/null 2>&1 && cc -c lex.yy.c > /dev/null 2>&1
|
||||
then :
|
||||
else echo "Sorry, your lex does not seem to work"
|
||||
exit 2
|
||||
fi
|
||||
cat > trylib <<'EOF'
|
||||
if cc lex.yy.o $1 > /dev/null 2>&1
|
||||
then
|
||||
rm -f lex.yy.* a.out
|
||||
exit 0
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
EOF
|
||||
if sh trylib $TRY
|
||||
then
|
||||
LEX=$TRY
|
||||
else
|
||||
exec $0 -ll $TRY
|
||||
fi
|
||||
;;
|
||||
*) if sh trylib $1
|
||||
then
|
||||
LEX=$1
|
||||
else
|
||||
TRIES="$2 and $1"
|
||||
FL=fail
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
case X$FL in
|
||||
Xfail) echo 'What option do I have to give to cc to get the LEX library?'
|
||||
echo "I tried " $TRIES "but these don't seem to work."
|
||||
echo -n 'LEX library option: '
|
||||
if read ANSWER
|
||||
then :
|
||||
else echo "Sorry, got EOF while reading your answer"
|
||||
exit 9
|
||||
fi
|
||||
exec $0 $ANSWER "$TRIES"
|
||||
;;
|
||||
Xsucces)
|
||||
for i in ../util/opt ../util/cgg ../util/ncgg ../lang/occam/comp ../modules/src/em_opt ../util/ceg/as_parser
|
||||
do
|
||||
( cd $i
|
||||
cp Makefile makefile
|
||||
ed - makefile << EOF
|
||||
/^LEXLIB/c
|
||||
LEXLIB = $LEX
|
||||
.
|
||||
w
|
||||
q
|
||||
EOF
|
||||
)
|
||||
done
|
||||
;;
|
||||
esac
|
||||
rm -f x.l trylib lex.yy.*
|
||||
echo echo "$LEX" > .Xlex
|
||||
chmod +x .Xlex
|
||||
echo "apparently, \"cc ... $LEX\" works"
|
||||
@ -1,5 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
if read ANS
|
||||
then echo
|
||||
else echo "Sorry, got EOF when reading your answer"
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
know_target=0
|
||||
case $SYSNAME in
|
||||
vax*|i386|sun*|sparc*|m68_sysV_0|m68020|mantra|pmds4|m68k4)
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
rm -f em_path.h
|
||||
echo "You will now be asked for the root directory of the ACK sources.
|
||||
This directory will not be changed by the installation process.
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
while :
|
||||
do
|
||||
echo $E_FLAG "Which system-call library do you want to install for the VAX?
|
||||
|
||||
0
first/hash
Executable file
0
first/hash
Executable file
@ -1,5 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
PATH=::$CONFIG/bin:$UTIL_HOME/bin:/usr/ccs/bin:/usr/ucb:$PATH
|
||||
@ -8,15 +6,8 @@ export PATH
|
||||
$SRC_HOME/first/create_dir $CONFIG
|
||||
$SRC_HOME/first/create_dir $CONFIG/bin
|
||||
|
||||
(
|
||||
# Slight complication here to ensure that the #! magic at the
|
||||
# beginning of TakeAction is preserved correctly.
|
||||
|
||||
head -1 $SRC_HOME/TakeAction
|
||||
echo "PATH=:$CONFIG/bin:$UTIL_HOME/bin:$PATH; export PATH"
|
||||
tail +2 $SRC_HOME/TakeAction
|
||||
) > $CONFIG/bin/TakeAction
|
||||
|
||||
echo "PATH=:$CONFIG/bin:$UTIL_HOME/bin:$PATH; export PATH" > $CONFIG/bin/TakeAction
|
||||
cat $SRC_HOME/TakeAction >> $CONFIG/bin/TakeAction
|
||||
sed '/^#PARAMS/r make_macros' < $SRC_HOME/first/mk_makefile > $CONFIG/bin/mk_makefile
|
||||
cp $SRC_HOME/first/create_dir $CONFIG/bin/create_dir
|
||||
cp $SRC_HOME/first/cp_dir $CONFIG/bin/cp_dir
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
while :
|
||||
do
|
||||
echo "The libraries will end up in the machine-independent part of the
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
for i in $DISABLE_LANG
|
||||
do
|
||||
ed -s $CONFIG/Action <<EOF
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
#!/usr/bin/make
|
||||
|
||||
# There are two choices for lint here: ACK lint and Unix lint.
|
||||
# The current setup is for ACK lint. If you want to use the Unix lint,
|
||||
|
||||
@ -1,37 +0,0 @@
|
||||
-- $Source$
|
||||
-- $State$
|
||||
|
||||
-- This is unpleasant. LLgen can generate an arbitrary number of output files,
|
||||
-- which means we need our own output filename generator.
|
||||
|
||||
LLgen = simple {
|
||||
class = "LLgen",
|
||||
command = {
|
||||
"rm -f %out%",
|
||||
"cd %out[1]:dirname% && %TOOLDIR%LLgen %in%"
|
||||
},
|
||||
|
||||
outputs = {"%U%/" },
|
||||
__outputs = function(self, inputs)
|
||||
local o = simple.__outputs(self, inputs)[1]
|
||||
|
||||
local outputs = {o.."Lpars.h", o.."Lpars.c"}
|
||||
|
||||
for _, i in ipairs(inputs) do
|
||||
i = string.gsub(i, "^.*/", "")
|
||||
i = string.gsub(i, "%.g$", ".c")
|
||||
table.insert(outputs, o..i)
|
||||
end
|
||||
|
||||
return outputs
|
||||
end
|
||||
}
|
||||
|
||||
-- Revision history
|
||||
-- $Log$
|
||||
-- Revision 1.2 2006-11-11 22:59:01 dtrg
|
||||
-- Now uses the version of LLgen included with the ACK instead of the standalone version.
|
||||
--
|
||||
-- Revision 1.1 2006/07/20 23:18:18 dtrg
|
||||
-- First version in CVS.
|
||||
--
|
||||
@ -1,12 +1,9 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
create_dir $CONFIG
|
||||
|
||||
create_dir $CONFIG/bin
|
||||
echo "#!/bin/sh" > $CONFIG/bin/ack_sys
|
||||
echo "echo $SYSNAME" >> $CONFIG/bin/ack_sys
|
||||
echo "echo $SYSNAME" > $CONFIG/bin/ack_sys
|
||||
chmod +x $CONFIG/bin/ack_sys
|
||||
|
||||
cd $SRC_HOME
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
#!/bin/sh
|
||||
: '$Id$'
|
||||
|
||||
: This shell script inserts make macros after a line
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
: machine-dependant stuff
|
||||
|
||||
21
first/myecho.c
Normal file
21
first/myecho.c
Normal file
@ -0,0 +1,21 @@
|
||||
#include <stdio.h>
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int nflag = 0;
|
||||
|
||||
if(argc > 1 && ! strncmp(argv[1], "-n", 2)) {
|
||||
nflag++;
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
while (--argc > 0) {
|
||||
fputs(argv[1], stdout);
|
||||
argv++;
|
||||
if (argc > 1) putchar(' ');
|
||||
}
|
||||
if (!nflag) putchar('\n');
|
||||
exit(0);
|
||||
}
|
||||
@ -1,4 +1,3 @@
|
||||
#!/bin/sh
|
||||
# compiler set for target machine
|
||||
|
||||
CC=cc# # compiler to be used for compiling ACK
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
|
||||
# compiler set for producing runnable binaries (possibly using $(UTIL_HOME)).
|
||||
# This must describe the compiler with which $(UTIL_HOME) has been compiled.
|
||||
# If $(TARGET_HOME) is identical to $(UTIL_HOME), which usually will be
|
||||
|
||||
@ -1,18 +0,0 @@
|
||||
yacc = simple {
|
||||
class = "yacc",
|
||||
outputs = {"%U%/%I%.c"},
|
||||
|
||||
command = {
|
||||
"yacc -t -b %out[1]:dirname%/y -d %in%",
|
||||
"mv %out[1]:dirname%/y.tab.c %out[1]%"
|
||||
}
|
||||
}
|
||||
|
||||
flex = simple {
|
||||
class = "flex",
|
||||
outputs = {"%U%/%I%.c"},
|
||||
|
||||
command = {
|
||||
"flex -s -t %in% > %out%"
|
||||
}
|
||||
}
|
||||
14
h/.distr
14
h/.distr
@ -1,19 +1,19 @@
|
||||
#Makefile
|
||||
Makefile
|
||||
arch.h
|
||||
bc_io.h
|
||||
bc_string.h
|
||||
#as_spec.h
|
||||
as_spec.h
|
||||
cg_pattern.h
|
||||
cgg_cg.h
|
||||
em_abs.h
|
||||
em_ego.h
|
||||
em_flag.h
|
||||
em_mes.h
|
||||
#em_mnem.h
|
||||
#em_pseu.h
|
||||
em_mnem.h
|
||||
em_pseu.h
|
||||
em_ptyp.h
|
||||
em_reg.h
|
||||
#em_spec.h
|
||||
em_spec.h
|
||||
out.h
|
||||
stb.h
|
||||
pc_err.h
|
||||
@ -24,6 +24,4 @@ ocm_chan.h
|
||||
ocm_parco.h
|
||||
ocm_proc.h
|
||||
m2_traps.h
|
||||
#ip_spec.h
|
||||
em_table
|
||||
con_float
|
||||
ip_spec.h
|
||||
|
||||
@ -6,12 +6,6 @@
|
||||
#define LINO_AD 0
|
||||
#define FILN_AD 4
|
||||
|
||||
/* ERANGE conflicts with a symbol in the ANSI C library. */
|
||||
|
||||
#ifdef ERANGE
|
||||
#undef ERANGE
|
||||
#endif
|
||||
|
||||
#define LINO (*(int *)(_hol0()+LINO_AD))
|
||||
#define FILN (*(char **)(_hol0()+FILN_AD))
|
||||
|
||||
|
||||
@ -3,13 +3,6 @@
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
|
||||
/* EBADF conflicts with the ANSI C definition. */
|
||||
|
||||
#ifdef EBADF
|
||||
#undef EBADF
|
||||
#endif
|
||||
|
||||
#define EARGC 64
|
||||
#define EEXP 65
|
||||
#define ELOG 66
|
||||
|
||||
26
h/pc_size.h
Normal file
26
h/pc_size.h
Normal file
@ -0,0 +1,26 @@
|
||||
/* $Header$ */
|
||||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
|
||||
/*fundamental */
|
||||
#define sz_byte 1
|
||||
#define sz_bool 1
|
||||
#define sz_char 1
|
||||
|
||||
/* target machine characteristics */
|
||||
/* variable (see pc.c) */
|
||||
#define sz_addr sizes[0]
|
||||
#define sz_real sizes[1]
|
||||
#define sz_head sizes[2]
|
||||
#define sz_buff sizes[3]
|
||||
#define sz_mset sizes[4]
|
||||
#define sz_iset sizes[5]
|
||||
#define sz_word sizes[6]
|
||||
#define sz_int sizes[7]
|
||||
#define sz_long sizes[8]
|
||||
|
||||
#define sz_last 8
|
||||
|
||||
#define sz_proc 2*sz_addr
|
||||
@ -1,19 +1,14 @@
|
||||
assert.h
|
||||
ctype.h
|
||||
errno.h
|
||||
fcntl.h
|
||||
grp.h
|
||||
math.h
|
||||
pwd.h
|
||||
setjmp.h
|
||||
stdio.h
|
||||
assert.h
|
||||
varargs.h
|
||||
math.h
|
||||
time.h
|
||||
pwd.h
|
||||
grp.h
|
||||
sgtty.h
|
||||
signal.h
|
||||
stdio.h
|
||||
time.h
|
||||
varargs.h
|
||||
sys/dir.h
|
||||
sys/errno.h
|
||||
sys/stat.h
|
||||
sys/stdtypes.h
|
||||
sys/types.h
|
||||
sys/timeb.h
|
||||
fcntl.h
|
||||
errno.h
|
||||
sys
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user