For PR1074:

Remove the projects/Stacker directory. LLVM is now free of dependency
on llvm-gcc.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33278 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Reid Spencer 2007-01-17 02:18:44 +00:00
parent 67bb0796dd
commit d203342a59
95 changed files with 0 additions and 43683 deletions

View File

@ -14,14 +14,7 @@ DIRS:= $(filter-out llvm-test,$(patsubst $(PROJ_SRC_DIR)/%/Makefile,%,$(wildcard
# Sparc cannot link shared libraries (libtool problem?) which Stacker uses
ifeq ($(ARCH), Sparc)
DIRS := $(filter-out Stacker, $(DIRS))
DIRS := $(filter-out sample, $(DIRS))
endif
# Universal builds can't build stacker, which uses llvm-gcc -S.
ifdef UNIVERSAL
DIRS := $(filter-out Stacker, $(DIRS))
endif
include $(PROJ_SRC_ROOT)/Makefile.rules

View File

@ -1,4 +0,0 @@
Makefile.common
config.log
config.status
mklib

View File

@ -1,11 +0,0 @@
##===- projects/Stacker/Makefile ---------------------------*- Makefile -*-===##
#
# This is the Stacker top-level Makefile
#
##===----------------------------------------------------------------------===##
LEVEL = .
DIRS = lib tools
EXTRA_DIST = test samples
include $(LEVEL)/Makefile.common

View File

@ -1,21 +0,0 @@
# Set the name of the project here
PROJECT_NAME := Stacker
# Set this variable to the top of the LLVM source tree.
LLVM_SRC_ROOT = @LLVM_SRC@
# Set this variable to the top level directory where LLVM was built
# (this is *not* the same as OBJ_ROOT as defined in LLVM's Makefile.config).
LLVM_OBJ_ROOT = @LLVM_OBJ@
# Set the directory root of this project's source files
PROJ_SRC_ROOT := $(subst //,/,@abs_top_srcdir@)
# Set the root directory of this project's object files
PROJ_OBJ_ROOT := $(subst //,/,@abs_top_objdir@)
# Set the root directory of this project's install prefix
PROJ_INSTALL_ROOT := @prefix@
# Include LLVM's Master Makefile.
include $(LLVM_OBJ_ROOT)/Makefile.common

View File

@ -1,2 +0,0 @@
aclocal.m4
autom4te.cache

View File

@ -1,18 +0,0 @@
#!/bin/sh
die () {
echo "$@" 1>&2
exit 1
}
test -d autoconf && test -f autoconf/configure.ac && cd autoconf
[ -f configure.ac ] || die "Can't find 'autoconf' dir; please cd into it first"
echo "Regenerating aclocal.m4 with aclocal"
aclocal || die "aclocal failed"
autoconf --version | egrep '2\.5[0-9]' > /dev/null
if test $? -ne 0
then
die "Your autoconf was not detected as being 2.5x"
fi
echo "Regenerating configure with autoconf 2.5x"
autoconf -o ../configure configure.ac || die "autoconf failed"
cd ..
exit 0

View File

@ -1,24 +0,0 @@
------------------------------------------------------------------------------
Autoconf Files
------------------------------------------------------------------------------
All autoconf files are licensed under the LLVM license with the following
additions:
llvm/autoconf/install-sh:
This script is licensed under the LLVM license, with the following
additional copyrights and restrictions:
Copyright 1991 by the Massachusetts Institute of Technology
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation, and that the name of M.I.T. not be used in advertising or
publicity pertaining to distribution of the software without specific,
written prior permission. M.I.T. makes no representations about the
suitability of this software for any purpose. It is provided "as is"
without express or implied warranty.
Please see the source files for additional copyrights.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,79 +0,0 @@
dnl **************************************************************************
dnl * Initialize
dnl **************************************************************************
AC_INIT([[[Stacker]]],[[[1.0]]],[rspencer@x10sys.com])
dnl Place all of the extra autoconf files into the config subdirectory
AC_CONFIG_AUX_DIR([autoconf])
dnl Verify that the source directory is valid
AC_CONFIG_SRCDIR([lib/compiler/StackerParser.y])
AC_CONFIG_FILES([Makefile.common])
dnl Configure Makefiles
dnl List every Makefile that exists within your source tree
AC_CONFIG_MAKEFILE(Makefile)
AC_CONFIG_MAKEFILE(lib/Makefile)
AC_CONFIG_MAKEFILE(lib/compiler/Makefile)
AC_CONFIG_MAKEFILE(lib/runtime/Makefile)
AC_CONFIG_MAKEFILE(test/Makefile)
AC_CONFIG_MAKEFILE(tools/Makefile)
AC_CONFIG_MAKEFILE(tools/stkrc/Makefile)
dnl **************************************************************************
dnl * Determine which system we are building on
dnl **************************************************************************
dnl **************************************************************************
dnl * Check for programs.
dnl **************************************************************************
AC_PROG_LIBTOOL
dnl Get libtool's idea of what the shared library suffix is.
dnl (This is a hack; it relies on undocumented behavior.)
AC_MSG_CHECKING([for shared library suffix])
eval "SHLIBEXT=$shrext"
AC_MSG_RESULT($SHLIBEXT)
dnl Propagate it to the Makefiles and config.h (for gccld & bugpoint).
AC_SUBST(SHLIBEXT,$SHLIBEXT)
AC_DEFINE_UNQUOTED(SHLIBEXT,"$SHLIBEXT",
[Extension that shared libraries have,
e.g., ".so".])
dnl **************************************************************************
dnl * Check for libraries.
dnl **************************************************************************
dnl **************************************************************************
dnl * Checks for header files.
dnl **************************************************************************
dnl **************************************************************************
dnl * Checks for typedefs, structures, and compiler characteristics.
dnl **************************************************************************
dnl **************************************************************************
dnl * Checks for library functions.
dnl **************************************************************************
dnl **************************************************************************
dnl * Enable various compile-time options
dnl **************************************************************************
dnl **************************************************************************
dnl * Set the location of various third-party software packages
dnl **************************************************************************
dnl Location of LLVM source code
AC_ARG_WITH(llvmsrc,AC_HELP_STRING([--with-llvmsrc],[Location of LLVM Source Code]),AC_SUBST(LLVM_SRC,[$withval]),AC_SUBST(LLVM_SRC,[`cd ${srcdir}/../..; pwd`]))
dnl Location of LLVM object code
AC_ARG_WITH(llvmobj,AC_HELP_STRING([--with-llvmobj],[Location of LLVM Object Code]),AC_SUBST(LLVM_OBJ,[$withval]),AC_SUBST(LLVM_OBJ,[`cd ../..; pwd`]))
dnl **************************************************************************
dnl * Create the output files
dnl **************************************************************************
AC_OUTPUT

View File

@ -1,251 +0,0 @@
#!/bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5 (mit/util/scripts/install.sh).
#
# Copyright 1991 by the Massachusetts Institute of Technology
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of M.I.T. not be used in advertising or
# publicity pertaining to distribution of the software without specific,
# written prior permission. M.I.T. makes no representations about the
# suitability of this software for any purpose. It is provided "as is"
# without express or implied warranty.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
:
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
chmodcmd=""
else
instcmd=$mkdirprog
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
then
:
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
:
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
:
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
:
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
:
fi
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
exit 0

File diff suppressed because it is too large Load Diff

View File

@ -1,101 +0,0 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Public domain
# $Id$
errstatus=0
dirmode=""
usage="\
Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..."
# process command line arguments
while test $# -gt 0 ; do
case "${1}" in
-h | --help | --h* ) # -h for help
echo "${usage}" 1>&2; exit 0 ;;
-m ) # -m PERM arg
shift
test $# -eq 0 && { echo "${usage}" 1>&2; exit 1; }
dirmode="${1}"
shift ;;
-- ) shift; break ;; # stop option processing
-* ) echo "${usage}" 1>&2; exit 1 ;; # unknown option
* ) break ;; # first non-opt arg
esac
done
for file
do
if test -d "$file"; then
shift
else
break
fi
done
case $# in
0) exit 0 ;;
esac
case $dirmode in
'')
if mkdir -p -- . 2>/dev/null; then
echo "mkdir -p -- $*"
exec mkdir -p -- "$@"
fi ;;
*)
if mkdir -m "$dirmode" -p -- . 2>/dev/null; then
echo "mkdir -m $dirmode -p -- $*"
exec mkdir -m "$dirmode" -p -- "$@"
fi ;;
esac
for file
do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift
pathcomp=
for d
do
pathcomp="$pathcomp$d"
case "$pathcomp" in
-* ) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp"
mkdir "$pathcomp" || lasterr=$?
if test ! -d "$pathcomp"; then
errstatus=$lasterr
else
if test ! -z "$dirmode"; then
echo "chmod $dirmode $pathcomp"
lasterr=""
chmod "$dirmode" "$pathcomp" || lasterr=$?
if test ! -z "$lasterr"; then
errstatus=$lasterr
fi
fi
fi
fi
pathcomp="$pathcomp/"
done
done
exit $errstatus
# Local Variables:
# mode: shell-script
# sh-indentation: 3
# End:
# mkinstalldirs ends here

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +0,0 @@
##===- projects/Stacker/lib/Makefile -----------------------*- Makefile -*-===##
#
# Compile Stacker libraries
#
##===----------------------------------------------------------------------===##
LEVEL = ..
DIRS = compiler runtime
include $(LEVEL)/Makefile.common
# Don't generate the runtime if we don't have LLVMGCC
ifeq ($(strip $(LLVMGCC)),)
DIRS := $(filter-out runtime, $(DIRS))
endif

View File

@ -1,4 +0,0 @@
Lexer.cpp
StackerParser.cpp
StackerParser.h
StackerParser.output

File diff suppressed because it is too large Load Diff

View File

@ -1,234 +0,0 @@
/*===-- Lexer.l - Scanner for Stacker language -----------------*- C++ -*--===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Reid Spencer and donated to the LLVM research
// group and is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the flex scanner for Stacker languages files.
//
//===----------------------------------------------------------------------===*/
%option prefix="Stacker"
%option yylineno
%option nostdinit
%option never-interactive
%option batch
%option noyywrap
%option nodefault
%option 8bit
%option outfile="Lexer.cpp"
%option ecs
%option noreject
%option noyymore
%{
#include "StackerCompiler.h"
#include "StackerParser.h"
/* Conversion of text ints to binary */
static int64_t IntToVal(const char *Buffer) {
int64_t Result = 0;
for (; *Buffer; Buffer++) {
int64_t OldRes = Result;
Result *= 10;
Result += *Buffer-'0';
if (Result < OldRes) // Uh, oh, overflow detected!!!
StackerCompiler::ThrowException("constant bigger than 64 bits detected!");
}
return Result;
}
/* Conversion of text hexadecimal ints to binary */
static int64_t HexIntToVal(const char *Buffer) {
int64_t Result = 0;
for (; *Buffer; ++Buffer) {
int64_t OldRes = Result;
Result *= 16;
char C = *Buffer;
if (C >= '0' && C <= '9')
Result += C-'0';
else if (C >= 'A' && C <= 'F')
Result += C-'A'+10;
else if (C >= 'a' && C <= 'f')
Result += C-'a'+10;
if (Result < OldRes) // Uh, oh, overflow detected!!!
StackerCompiler::ThrowException("constant bigger than 64 bits detected!");
}
return Result;
}
#define YY_NEVER_INTERACTIVE 1
%}
/* Comments start with a ; and go till end of line */
Comment1 [#].*$
/* You can also embed them in ( ... ) */
Comment2 \(.*\)
/* We ignore white space */
White [ \t\r\n]
/* jdentifiers start with a % sign */
Identifier [A-Za-z][-A-Za-z0-9_]*
/* Strings can contain any character except " and \ */
String \"[^\"]*\"
/* Positive and negative integer constants*/
PInteger [+]?[0-9]+
NInteger -[0-9]+
HexInteger 0x[0-9A-Fa-f]+
/* Special Characters - name them to avoid flex confusion */
Semi [;]
Colon [:]
Less \<
More \>
LessEq \<\=
MoreEq \>\=
NotEq \<\>
Equal \=
Plus \+
Minus \-
Incr \+\+
Decr \-\-
Mult \*
Div \/
StarSlash \*\/
LShift \<\<
RShift \>\>
InStr \<s
InNum \<d
InChar \<c
OutStr \>s
OutNum \>d
OutChar \>c
%%
{Comment1} { /* Ignore comments */ }
{Comment2} { /* Ignore comments */ }
{Colon} { return COLON; }
{Semi} { return SEMI; }
TRUE { return TRUETOK; }
FALSE { return FALSETOK; }
ON { return TRUETOK; }
OFF { return FALSETOK; }
{Less} { return LESS; }
LT { return LESS; }
{More} { return MORE; }
GT { return MORE; }
{LessEq} { return LESS_EQUAL; }
LE { return LESS_EQUAL; }
{MoreEq} { return MORE_EQUAL; }
GE { return MORE_EQUAL; }
{NotEq} { return NOT_EQUAL; }
NE { return NOT_EQUAL; }
{Equal} { return EQUAL; }
EQ { return EQUAL; }
{Plus} { return PLUS; }
{Minus} { return MINUS; }
{Incr} { return INCR; }
{Decr} { return DECR; }
{Mult} { return MULT; }
{Div} { return DIV; }
MOD { return MODULUS; }
NEG { return NEGATE; }
ABS { return ABS; }
MIN { return MIN; }
MAX { return MAX; }
{StarSlash} { return STAR_SLASH; }
AND { return AND; }
OR { return OR; }
XOR { return XOR; }
{LShift} { return LSHIFT; }
{RShift} { return RSHIFT; }
DROP { return DROP; }
NIP { return NIP; }
DUP { return DUP; }
SWAP { return SWAP; }
OVER { return OVER; }
PICK { return PICK; }
SELECT { return SELECT; }
ROT { return ROT; }
RROT { return RROT; }
ROLL { return ROLL; }
TUCK { return TUCK; }
DROP2 { return DROP2; }
NIP2 { return NIP2; }
DUP2 { return DUP2; }
SWAP2 { return SWAP2; }
OVER2 { return OVER2; }
TUCK2 { return TUCK2; }
ROT2 { return ROT2; }
RROT2 { return RROT2; }
MALLOC { return MALLOC; }
FREE { return FREE; }
GET { return GET; }
PUT { return PUT; }
IF { return IF; }
ELSE { return ELSE; }
ENDIF { return ENDIF; }
WHILE { return WHILE; }
END { return END; }
RECURSE { return RECURSE; }
RETURN { return RETURN; }
EXIT { return EXIT; }
FORWARD { return FORWARD; }
TAB { return TAB; }
SPACE { return SPACE; }
CR { return CR; }
{InStr} { return IN_STR; }
{InNum} { return IN_NUM; }
{InChar} { return IN_CHAR; }
{OutStr} { return OUT_STR; }
{OutNum} { return OUT_NUM; }
{OutChar} { return OUT_CHAR; }
MAIN { return MAIN; }
DUMP { return DUMP; }
!= { StackerCompiler::ThrowException(
"You probably meant to use a <> instead of !=" ); }
== { StackerCompiler::ThrowException(
"You probably meant to use a single = .. this isn't C"); }
{PInteger} { Stackerlval.IntegerVal = IntToVal(yytext); return INTEGER; }
{NInteger} { uint64_t Val = IntToVal(yytext+1);
// +1: we have bigger negative range
if (Val > (uint64_t)INT64_MAX+1)
StackerCompiler::ThrowException(
"Constant too large for signed 64 bits!");
Stackerlval.IntegerVal = -Val;
return INTEGER;
}
{HexInteger} { Stackerlval.IntegerVal = HexIntToVal(yytext+3);
return INTEGER;
}
{String} { yytext[strlen(yytext)-1] = 0; // nuke end quote
Stackerlval.StringVal = strdup(yytext+1); // Nuke start quote
return STRING;
}
{Identifier} { Stackerlval.StringVal = strdup(yytext); return IDENTIFIER; }
{White} { /* Ignore whitespace */ }
%%

View File

@ -1,234 +0,0 @@
/*===-- Lexer.l - Scanner for Stacker language -----------------*- C++ -*--===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Reid Spencer and donated to the LLVM research
// group and is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the flex scanner for Stacker languages files.
//
//===----------------------------------------------------------------------===*/
%option prefix="Stacker"
%option yylineno
%option nostdinit
%option never-interactive
%option batch
%option noyywrap
%option nodefault
%option 8bit
%option outfile="Lexer.cpp"
%option ecs
%option noreject
%option noyymore
%{
#include "StackerCompiler.h"
#include "StackerParser.h"
/* Conversion of text ints to binary */
static int64_t IntToVal(const char *Buffer) {
int64_t Result = 0;
for (; *Buffer; Buffer++) {
int64_t OldRes = Result;
Result *= 10;
Result += *Buffer-'0';
if (Result < OldRes) // Uh, oh, overflow detected!!!
StackerCompiler::ThrowException("constant bigger than 64 bits detected!");
}
return Result;
}
/* Conversion of text hexadecimal ints to binary */
static int64_t HexIntToVal(const char *Buffer) {
int64_t Result = 0;
for (; *Buffer; ++Buffer) {
int64_t OldRes = Result;
Result *= 16;
char C = *Buffer;
if (C >= '0' && C <= '9')
Result += C-'0';
else if (C >= 'A' && C <= 'F')
Result += C-'A'+10;
else if (C >= 'a' && C <= 'f')
Result += C-'a'+10;
if (Result < OldRes) // Uh, oh, overflow detected!!!
StackerCompiler::ThrowException("constant bigger than 64 bits detected!");
}
return Result;
}
#define YY_NEVER_INTERACTIVE 1
%}
/* Comments start with a ; and go till end of line */
Comment1 [#].*$
/* You can also embed them in ( ... ) */
Comment2 \(.*\)
/* We ignore white space */
White [ \t\r\n]
/* jdentifiers start with a % sign */
Identifier [A-Za-z][-A-Za-z0-9_]*
/* Strings can contain any character except " and \ */
String \"[^\"]*\"
/* Positive and negative integer constants*/
PInteger [+]?[0-9]+
NInteger -[0-9]+
HexInteger 0x[0-9A-Fa-f]+
/* Special Characters - name them to avoid flex confusion */
Semi [;]
Colon [:]
Less \<
More \>
LessEq \<\=
MoreEq \>\=
NotEq \<\>
Equal \=
Plus \+
Minus \-
Incr \+\+
Decr \-\-
Mult \*
Div \/
StarSlash \*\/
LShift \<\<
RShift \>\>
InStr \<s
InNum \<d
InChar \<c
OutStr \>s
OutNum \>d
OutChar \>c
%%
{Comment1} { /* Ignore comments */ }
{Comment2} { /* Ignore comments */ }
{Colon} { return COLON; }
{Semi} { return SEMI; }
TRUE { return TRUETOK; }
FALSE { return FALSETOK; }
ON { return TRUETOK; }
OFF { return FALSETOK; }
{Less} { return LESS; }
LT { return LESS; }
{More} { return MORE; }
GT { return MORE; }
{LessEq} { return LESS_EQUAL; }
LE { return LESS_EQUAL; }
{MoreEq} { return MORE_EQUAL; }
GE { return MORE_EQUAL; }
{NotEq} { return NOT_EQUAL; }
NE { return NOT_EQUAL; }
{Equal} { return EQUAL; }
EQ { return EQUAL; }
{Plus} { return PLUS; }
{Minus} { return MINUS; }
{Incr} { return INCR; }
{Decr} { return DECR; }
{Mult} { return MULT; }
{Div} { return DIV; }
MOD { return MODULUS; }
NEG { return NEGATE; }
ABS { return ABS; }
MIN { return MIN; }
MAX { return MAX; }
{StarSlash} { return STAR_SLASH; }
AND { return AND; }
OR { return OR; }
XOR { return XOR; }
{LShift} { return LSHIFT; }
{RShift} { return RSHIFT; }
DROP { return DROP; }
NIP { return NIP; }
DUP { return DUP; }
SWAP { return SWAP; }
OVER { return OVER; }
PICK { return PICK; }
SELECT { return SELECT; }
ROT { return ROT; }
RROT { return RROT; }
ROLL { return ROLL; }
TUCK { return TUCK; }
DROP2 { return DROP2; }
NIP2 { return NIP2; }
DUP2 { return DUP2; }
SWAP2 { return SWAP2; }
OVER2 { return OVER2; }
TUCK2 { return TUCK2; }
ROT2 { return ROT2; }
RROT2 { return RROT2; }
MALLOC { return MALLOC; }
FREE { return FREE; }
GET { return GET; }
PUT { return PUT; }
IF { return IF; }
ELSE { return ELSE; }
ENDIF { return ENDIF; }
WHILE { return WHILE; }
END { return END; }
RECURSE { return RECURSE; }
RETURN { return RETURN; }
EXIT { return EXIT; }
FORWARD { return FORWARD; }
TAB { return TAB; }
SPACE { return SPACE; }
CR { return CR; }
{InStr} { return IN_STR; }
{InNum} { return IN_NUM; }
{InChar} { return IN_CHAR; }
{OutStr} { return OUT_STR; }
{OutNum} { return OUT_NUM; }
{OutChar} { return OUT_CHAR; }
MAIN { return MAIN; }
DUMP { return DUMP; }
!= { StackerCompiler::ThrowException(
"You probably meant to use a <> instead of !=" ); }
== { StackerCompiler::ThrowException(
"You probably meant to use a single = .. this isn't C"); }
{PInteger} { Stackerlval.IntegerVal = IntToVal(yytext); return INTEGER; }
{NInteger} { uint64_t Val = IntToVal(yytext+1);
// +1: we have bigger negative range
if (Val > (uint64_t)INT64_MAX+1)
StackerCompiler::ThrowException(
"Constant too large for signed 64 bits!");
Stackerlval.IntegerVal = -Val;
return INTEGER;
}
{HexInteger} { Stackerlval.IntegerVal = HexIntToVal(yytext+3);
return INTEGER;
}
{String} { yytext[strlen(yytext)-1] = 0; // nuke end quote
Stackerlval.StringVal = strdup(yytext+1); // Nuke start quote
return STRING;
}
{Identifier} { Stackerlval.StringVal = strdup(yytext); return IDENTIFIER; }
{White} { /* Ignore whitespace */ }
%%

View File

@ -1,21 +0,0 @@
##===- projects/Stacker/lib/compiler/Makefile --------------*- Makefile -*-===##
LEVEL := ../..
LIBRARYNAME := stkr_compiler
EXTRA_DIST := Lexer.cpp.cvs Lexer.l.cvs \
StackerParser.cpp.cvs StackerParser.h.cvs StackerParser.y.cvs
REQUIRES_EH := 1
include $(LEVEL)/Makefile.common
ifdef PARSE_DEBUG
INCLUDES += -DPARSE_DEBUG
endif
# Disable -pedantic for this library, as bison output isn't necessarily
# -pedantic clean.
CompileCommonOpts := $(filter-out -pedantic,$(CompileCommonOpts))
CompileCommonOpts := $(filter-out -Wno-long-long,$(CompileCommonOpts))
$(ObjDir)/Lexer.o : $(PROJ_SRC_DIR)/StackerParser.h
$(ObjDir)/StackerCompiler.o : $(PROJ_SRC_DIR)/StackerParser.h

View File

@ -1,20 +0,0 @@
This directory contains a sample language front end for LLVM.
It is a *very* simple/crude implementation of FORTH. It has many
deficiencies but provides enough basics to give you an idea of
what programming a new language front end for LLVM looks like.
To keep things simple, Stacker has the following limitations:
1. Only a single, global stack is manipulated.
2. There is no interpretation, everything is compiled.
3. There's no type/bounds checking .. you're on your own.
4. There's no floating point support.
5. Only stdin can be read. Only stdout can be written. No other
file I/O is supported.
As such, this isn't a very useful language for anything other than
the most trivial of programs. It is, however, a good learning tool
(for both the author and the student).
Reid Spencer
16 November 2003

File diff suppressed because it is too large Load Diff

View File

@ -1,224 +0,0 @@
//===-- StackerCompiler.h - Interface to the Stacker Compiler ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Reid Spencer and donated to the LLVM research
// group and is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This header file defines the various variables that are shared among the
// different components of the parser...
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_STACKERCOMPILER_H
#define LLVM_STACKERCOMPILER_H
#include <llvm/Constants.h>
#include <llvm/DerivedTypes.h>
#include <llvm/Function.h>
#include <llvm/Instruction.h>
#include <llvm/Module.h>
#include <llvm/Assembly/Parser.h>
#include <llvm/ADT/StringExtras.h>
using namespace llvm;
// Global variables exported from the lexer...
extern std::FILE *Stackerin;
extern int Stackerlineno;
extern char* Stackertext;
extern int Stackerleng;
/// @brief This class provides the Compiler for the Stacker language.
///
/// The main method to call is \c compile. The other methods are
/// all internal to the compiler and protected. In general the
/// handle_* methods are called by the BISON generated parser
/// (see StackerParser.y). The methods returning Instruction* all
/// produce some snippet of code to manipulate the stack in some
/// way. These functions are just conveniences as they are used
/// often by the compiler.
class StackerCompiler
{
/// @name Constructors and Operators
/// @{
public:
/// Default Constructor
StackerCompiler();
/// Destructor
~StackerCompiler();
private:
/// Do not copy StackerCompilers
StackerCompiler(const StackerCompiler&);
/// Do not copy StackerCompilers.
StackerCompiler& operator=(const StackerCompiler& );
/// @}
/// @name High Level Interface
/// @{
public:
/// @brief Compile a single file to LLVM bytecode.
///
/// To use the StackerCompiler, just create one on
/// the stack and call this method.
Module* compile(
const std::string& filename, ///< File to compile
bool echo, ///< Causes compiler to echo output
unsigned optLevel, ///< Level of optimization
size_t stack_size ); ///< Size of generated stack
/// @}
/// @name Accessors
/// @{
public:
/// @brief Returns the name of the file being compiled.
std::string& filename() { return CurFilename; }
/// @}
/// @name Parse Handling Methods
/// @{
private:
/// Allow only the parser to access these methods. No
/// one else should call them.
friend int Stackerparse();
/// @brief Handle the start of a module
Module* handle_module_start();
/// @brief Handle the end of a module
/// @param mod The module we're defining.
Module* handle_module_end( Module* mod );
/// @brief Handle the start of a list of definitions
Module* handle_definition_list_start( );
/// @brief Handle the end of a list of definitions
/// @param mod The module we're constructing
/// @param definition A definition (function) to add to the module
Module* handle_definition_list_end( Module* mod, Function* definition );
/// @brief Handle creation of the MAIN definition
/// @param func The function to be used as the MAIN definition
Function* handle_main_definition( Function* func );
/// @brief Handle a forward definition
/// @param name The name of the definition being declared
Function* handle_forward( char* name );
/// @brief Handle a general definition
/// @param name The name of the definition being defined
/// @param func The Function definition.
Function* handle_definition( char* name, Function* func );
/// @brief Handle the start of a definition's word list
Function* handle_word_list_start();
/// @brief Handle the end of a definition's word list
/// @param func The function to which the basic block is added
/// @param next The block to add to the function
Function* handle_word_list_end( Function* func, BasicBlock* next );
/// @brief Handle an if statement, possibly without an else
/// @brief ifTrue The block to execute if true
/// @brief ifFalse The optional block to execute if false
BasicBlock* handle_if( char* ifTrue, char* ifFalse = 0 );
/// @brief Handle a while statement
/// @brief todo The block to repeatedly execute
BasicBlock* handle_while( char* todo );
/// @brief Handle an identifier to call the identified definition
/// @param name The name of the identifier to be called.
BasicBlock* handle_identifier( char * name );
/// @brief Handle the push of a string onto the stack
/// @param value The string to be pushed.
BasicBlock* handle_string( char * value );
/// @brief Handle the push of an integer onto the stack.
/// @param value The integer value to be pushed.
BasicBlock* handle_integer( const int64_t value );
/// @brief Handle one of the reserved words (given as a token)
BasicBlock* handle_word( int tkn );
/// @}
/// @name Utility functions
/// @{
public:
/// @brief Throws an exception to indicate an error
/// @param message The message to be output
/// @param line Override for the current line no
static inline void ThrowException( const std::string &message,
int line = -1)
{
if (line == -1) line = Stackerlineno;
// TODO: column number in exception
ParseError Err;
Err.setError(TheInstance->CurFilename, message, line);
throw Err;
}
private:
/// @brief Generate code to increment the stack index
Instruction* incr_stack_index( BasicBlock* bb, Value* );
/// @brief Generate code to decrement the stack index.
Instruction* decr_stack_index( BasicBlock* bb, Value* );
/// @brief Generate code to dereference the top of stack.
Instruction* get_stack_pointer( BasicBlock* bb, Value* );
/// @brief Generate code to push any value onto the stack.
Instruction* push_value( BasicBlock* bb, Value* value );
/// @brief Generate code to push a constant integer onto the stack.
Instruction* push_integer( BasicBlock* bb, int64_t value );
/// @brief Generate code to pop an integer off the stack.
Instruction* pop_integer( BasicBlock* bb );
/// @brief Generate code to push a string pointer onto the stack.
Instruction* push_string( BasicBlock* bb, const char* value );
/// @brief Generate code to pop a string pointer off the stack.
Instruction* pop_string( BasicBlock* bb );
/// @brief Generate code to get the top stack element.
Instruction* stack_top( BasicBlock* bb, Value* index );
/// @brief Generate code to get the top stack element as a string.
Instruction* stack_top_string( BasicBlock* bb, Value* index );
/// @brief Generate code to replace the top element of the stack.
Instruction* replace_top( BasicBlock* bb, Value* new_top, Value* index);
/// @}
/// @name Data Members (used during parsing)
/// @{
public:
static StackerCompiler* TheInstance; ///< The instance for the parser
private:
std::string CurFilename; ///< Current file name
Module* TheModule; ///< Module instance we'll build
Function* TheFunction; ///< Function we're building
FunctionType* DefinitionType; ///< FT for Definitions
GlobalVariable* TheStack; ///< For referencing _stack_
GlobalVariable* TheIndex; ///< For referencing _index_
Function* TheScanf; ///< External input function
Function* ThePrintf; ///< External output function
Function* TheExit; ///< External exit function
GlobalVariable* StrFormat; ///< Format for strings
GlobalVariable* NumFormat; ///< Format for numbers
GlobalVariable* ChrFormat; ///< Format for chars
GlobalVariable* InStrFormat; ///< Format for input strings
GlobalVariable* InNumFormat; ///< Format for input numbers
GlobalVariable* InChrFormat; ///< Format for input chars
ConstantInt* Zero; ///< long constant 0
ConstantInt* One; ///< long constant 1
ConstantInt* Two; ///< long constant 2
ConstantInt* Three; ///< long constant 3
ConstantInt* Four; ///< long constant 4
ConstantInt* Five; ///< long constant 5
std::vector<Value*> no_arguments; ///< no arguments for Stacker
bool echo; ///< Echo flag
size_t stack_size; ///< Size of stack to gen.
ArrayType* stack_type; ///< The type of the stack
/// @}
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,203 +0,0 @@
/* A Bison parser, made by GNU Bison 1.875c. */
/* Skeleton parser for Yacc-like parsing with Bison,
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, when this file is copied by Bison into a
Bison output file, you may use that output file without restriction.
This special exception was added by the Free Software Foundation
in version 1.24 of Bison. */
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum yytokentype {
INTEGER = 258,
STRING = 259,
IDENTIFIER = 260,
SEMI = 261,
COLON = 262,
FORWARD = 263,
MAIN = 264,
DUMP = 265,
TRUETOK = 266,
FALSETOK = 267,
LESS = 268,
MORE = 269,
LESS_EQUAL = 270,
MORE_EQUAL = 271,
NOT_EQUAL = 272,
EQUAL = 273,
PLUS = 274,
MINUS = 275,
INCR = 276,
DECR = 277,
MULT = 278,
DIV = 279,
MODULUS = 280,
NEGATE = 281,
ABS = 282,
MIN = 283,
MAX = 284,
STAR_SLASH = 285,
AND = 286,
OR = 287,
XOR = 288,
LSHIFT = 289,
RSHIFT = 290,
DROP = 291,
DROP2 = 292,
NIP = 293,
NIP2 = 294,
DUP = 295,
DUP2 = 296,
SWAP = 297,
SWAP2 = 298,
OVER = 299,
OVER2 = 300,
ROT = 301,
ROT2 = 302,
RROT = 303,
RROT2 = 304,
TUCK = 305,
TUCK2 = 306,
ROLL = 307,
PICK = 308,
SELECT = 309,
MALLOC = 310,
FREE = 311,
GET = 312,
PUT = 313,
IF = 314,
ELSE = 315,
ENDIF = 316,
WHILE = 317,
END = 318,
RECURSE = 319,
RETURN = 320,
EXIT = 321,
TAB = 322,
SPACE = 323,
CR = 324,
IN_STR = 325,
IN_NUM = 326,
IN_CHAR = 327,
OUT_STR = 328,
OUT_NUM = 329,
OUT_CHAR = 330
};
#endif
#define INTEGER 258
#define STRING 259
#define IDENTIFIER 260
#define SEMI 261
#define COLON 262
#define FORWARD 263
#define MAIN 264
#define DUMP 265
#define TRUETOK 266
#define FALSETOK 267
#define LESS 268
#define MORE 269
#define LESS_EQUAL 270
#define MORE_EQUAL 271
#define NOT_EQUAL 272
#define EQUAL 273
#define PLUS 274
#define MINUS 275
#define INCR 276
#define DECR 277
#define MULT 278
#define DIV 279
#define MODULUS 280
#define NEGATE 281
#define ABS 282
#define MIN 283
#define MAX 284
#define STAR_SLASH 285
#define AND 286
#define OR 287
#define XOR 288
#define LSHIFT 289
#define RSHIFT 290
#define DROP 291
#define DROP2 292
#define NIP 293
#define NIP2 294
#define DUP 295
#define DUP2 296
#define SWAP 297
#define SWAP2 298
#define OVER 299
#define OVER2 300
#define ROT 301
#define ROT2 302
#define RROT 303
#define RROT2 304
#define TUCK 305
#define TUCK2 306
#define ROLL 307
#define PICK 308
#define SELECT 309
#define MALLOC 310
#define FREE 311
#define GET 312
#define PUT 313
#define IF 314
#define ELSE 315
#define ENDIF 316
#define WHILE 317
#define END 318
#define RECURSE 319
#define RETURN 320
#define EXIT 321
#define TAB 322
#define SPACE 323
#define CR 324
#define IN_STR 325
#define IN_NUM 326
#define IN_CHAR 327
#define OUT_STR 328
#define OUT_NUM 329
#define OUT_CHAR 330
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
#line 35 "/proj/llvm/build/projects/Stacker/../../../llvm/projects/Stacker/lib/compiler/StackerParser.y"
typedef union YYSTYPE {
llvm::Module* ModuleVal;
llvm::Function* FunctionVal;
llvm::BasicBlock* BasicBlockVal;
int64_t IntegerVal;
char* StringVal;
} YYSTYPE;
/* Line 1275 of yacc.c. */
#line 195 "StackerParser.tab.h"
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif
extern YYSTYPE Stackerlval;

View File

@ -1,185 +0,0 @@
//===-- StackerParser.y - Parser for Stacker programs -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the bison parser for Stacker programs.
//
//===----------------------------------------------------------------------===//
%{
#include "StackerCompiler.h"
#include "llvm/SymbolTable.h"
#include "llvm/Module.h"
#include "llvm/Instructions.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include <list>
#include <utility>
#include <algorithm>
#define YYERROR_VERBOSE 1
#define SCI StackerCompiler::TheInstance
int yyerror(const char *ErrorMsg); // Forward declarations to prevent "implicit
int yylex(); // declaration" of xxx warnings.
int yyparse();
%}
%union
{
llvm::Module* ModuleVal;
llvm::Function* FunctionVal;
llvm::BasicBlock* BasicBlockVal;
int64_t IntegerVal;
char* StringVal;
}
/* Typed Productions */
%type <ModuleVal> Module DefinitionList
%type <FunctionVal> Definition ForwardDef ColonDef MainDef
%type <FunctionVal> WordList
%type <BasicBlockVal> Word
/* Typed Tokens */
%token <IntegerVal> INTEGER
%token <StringVal> STRING IDENTIFIER
/* Terminal Tokens */
%token SEMI COLON FORWARD MAIN DUMP
%token TRUETOK FALSETOK LESS MORE LESS_EQUAL MORE_EQUAL NOT_EQUAL EQUAL
%token PLUS MINUS INCR DECR MULT DIV MODULUS NEGATE ABS MIN MAX STAR_SLASH
%token AND OR XOR LSHIFT RSHIFT
%token DROP DROP2 NIP NIP2 DUP DUP2 SWAP SWAP2 OVER OVER2 ROT ROT2
%token RROT RROT2 TUCK TUCK2 ROLL PICK SELECT
%token MALLOC FREE GET PUT
%token IF ELSE ENDIF WHILE END RECURSE RETURN EXIT
%token TAB SPACE CR IN_STR IN_NUM IN_CHAR OUT_STR OUT_NUM OUT_CHAR
/* Start Token */
%start Module
%%
/* A module is just a DefinitionList */
Module : { SCI->handle_module_start( ); }
DefinitionList { $$ = SCI->handle_module_end( $2 ); } ;
/* A Definitionlist is just a sequence of definitions */
DefinitionList : DefinitionList Definition { $$ = SCI->handle_definition_list_end( $1, $2 ); }
| /* empty */ { $$ = SCI->handle_definition_list_start(); } ;
/* A definition can be one of three flavors */
Definition : ForwardDef { $$ = $1; }
| ColonDef { $$ = $1; }
| MainDef { $$ = $1; } ;
/* Forward definitions just introduce a name */
ForwardDef : FORWARD IDENTIFIER SEMI { $$ = SCI->handle_forward( $2 ); } ;
/* The main definition has to generate additional code so we treat it specially */
MainDef : COLON MAIN WordList SEMI { $$ = SCI->handle_main_definition($3); } ;
/* Regular definitions have a name and a WordList */
ColonDef : COLON IDENTIFIER WordList SEMI { $$ = SCI->handle_definition( $2, $3 ); } ;
/* A WordList is just a sequence of words */
WordList : WordList Word { $$ = SCI->handle_word_list_end( $1, $2 ); }
| /* empty */ { $$ = SCI->handle_word_list_start(); } ;
/* A few "words" have a funky syntax */
/* FIXME: The body of compound words can currently only be function calls */
/* This is not acceptable, it should be a WordList, but that produces a Function */
/* Which is hard to merge into the function the compound statement is working on */
Word : IF IDENTIFIER ELSE IDENTIFIER ENDIF { $$ = SCI->handle_if( $2, $4 ); }
| IF IDENTIFIER ENDIF { $$ = SCI->handle_if( $2 ); }
| WHILE IDENTIFIER END { $$ = SCI->handle_while( $2 ); } ;
/* A few words are handled specially */
Word : IDENTIFIER { $$ = SCI->handle_identifier( $1 ); } ;
Word : STRING { $$ = SCI->handle_string( $1 ); } ;
Word : INTEGER { $$ = SCI->handle_integer( $1 ); } ;
/* Everything else is a terminal symbol and goes to handle_word */
Word : TRUETOK { $$ = SCI->handle_word( TRUETOK ); } ;
Word : FALSETOK { $$ = SCI->handle_word( FALSETOK ); } ;
Word : LESS { $$ = SCI->handle_word( LESS ); } ;
Word : MORE { $$ = SCI->handle_word( MORE ); } ;
Word : LESS_EQUAL { $$ = SCI->handle_word( LESS_EQUAL ); } ;
Word : MORE_EQUAL { $$ = SCI->handle_word( MORE_EQUAL ); } ;
Word : NOT_EQUAL { $$ = SCI->handle_word( NOT_EQUAL ); } ;
Word : EQUAL { $$ = SCI->handle_word( EQUAL ); } ;
Word : PLUS { $$ = SCI->handle_word( PLUS ); } ;
Word : MINUS { $$ = SCI->handle_word( MINUS ); } ;
Word : INCR { $$ = SCI->handle_word( INCR ); } ;
Word : DECR { $$ = SCI->handle_word( DECR ); } ;
Word : MULT { $$ = SCI->handle_word( MULT ); } ;
Word : DIV { $$ = SCI->handle_word( DIV ); } ;
Word : MODULUS { $$ = SCI->handle_word( MODULUS ); } ;
Word : NEGATE { $$ = SCI->handle_word( NEGATE ); } ;
Word : ABS { $$ = SCI->handle_word( ABS ); } ;
Word : MIN { $$ = SCI->handle_word( MIN ); } ;
Word : MAX { $$ = SCI->handle_word( MAX ); } ;
Word : STAR_SLASH { $$ = SCI->handle_word( STAR_SLASH ); } ;
Word : AND { $$ = SCI->handle_word( AND ); } ;
Word : OR { $$ = SCI->handle_word( OR ); } ;
Word : XOR { $$ = SCI->handle_word( XOR ); } ;
Word : LSHIFT { $$ = SCI->handle_word( LSHIFT ); } ;
Word : RSHIFT { $$ = SCI->handle_word( RSHIFT ); } ;
Word : DROP { $$ = SCI->handle_word( DROP ); } ;
Word : DROP2 { $$ = SCI->handle_word( DROP2 ); } ;
Word : NIP { $$ = SCI->handle_word( NIP ); } ;
Word : NIP2 { $$ = SCI->handle_word( NIP2 ); } ;
Word : DUP { $$ = SCI->handle_word( DUP ); } ;
Word : DUP2 { $$ = SCI->handle_word( DUP2 ); } ;
Word : SWAP { $$ = SCI->handle_word( SWAP ); } ;
Word : SWAP2 { $$ = SCI->handle_word( SWAP2 ); } ;
Word : OVER { $$ = SCI->handle_word( OVER ); } ;
Word : OVER2 { $$ = SCI->handle_word( OVER2 ); } ;
Word : ROT { $$ = SCI->handle_word( ROT ); } ;
Word : ROT2 { $$ = SCI->handle_word( ROT2 ); } ;
Word : RROT { $$ = SCI->handle_word( RROT ); } ;
Word : RROT2 { $$ = SCI->handle_word( RROT2 ); } ;
Word : TUCK { $$ = SCI->handle_word( TUCK ); } ;
Word : TUCK2 { $$ = SCI->handle_word( TUCK2 ); } ;
Word : ROLL { $$ = SCI->handle_word( ROLL ); } ;
Word : PICK { $$ = SCI->handle_word( PICK ); } ;
Word : SELECT { $$ = SCI->handle_word( SELECT ); } ;
Word : MALLOC { $$ = SCI->handle_word( MALLOC ); } ;
Word : FREE { $$ = SCI->handle_word( FREE ); } ;
Word : GET { $$ = SCI->handle_word( GET ); } ;
Word : PUT { $$ = SCI->handle_word( PUT ); } ;
Word : RECURSE { $$ = SCI->handle_word( RECURSE ); } ;
Word : RETURN { $$ = SCI->handle_word( RETURN ); } ;
Word : EXIT { $$ = SCI->handle_word( EXIT ); } ;
Word : TAB { $$ = SCI->handle_word( TAB ); };
Word : SPACE { $$ = SCI->handle_word( SPACE ); } ;
Word : CR { $$ = SCI->handle_word( CR ); } ;
Word : IN_STR { $$ = SCI->handle_word( IN_STR ); } ;
Word : IN_NUM { $$ = SCI->handle_word( IN_NUM ); } ;
Word : IN_CHAR { $$ = SCI->handle_word( IN_CHAR ); } ;
Word : OUT_STR { $$ = SCI->handle_word( OUT_STR ); } ;
Word : OUT_NUM { $$ = SCI->handle_word( OUT_NUM ); } ;
Word : OUT_CHAR { $$ = SCI->handle_word( OUT_CHAR ); } ;
Word : DUMP { $$ = SCI->handle_word( DUMP ); } ;
%%
/* Handle messages a little more nicely than the default yyerror */
int yyerror(const char *ErrorMsg) {
std::string where
= std::string((SCI->filename() == "-") ? std::string("<stdin>") : SCI->filename())
+ ":" + utostr((unsigned) Stackerlineno ) + ": ";
std::string errMsg = std::string(ErrorMsg) + "\n" + where + " while reading ";
if (yychar == YYEMPTY)
errMsg += "end-of-file.";
else
errMsg += "token: '" + std::string(Stackertext, Stackerleng) + "'";
StackerCompiler::ThrowException(errMsg);
return 0;
}

View File

@ -1,185 +0,0 @@
//===-- StackerParser.y - Parser for Stacker programs -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the bison parser for Stacker programs.
//
//===----------------------------------------------------------------------===//
%{
#include "StackerCompiler.h"
#include "llvm/SymbolTable.h"
#include "llvm/Module.h"
#include "llvm/Instructions.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include <list>
#include <utility>
#include <algorithm>
#define YYERROR_VERBOSE 1
#define SCI StackerCompiler::TheInstance
int yyerror(const char *ErrorMsg); // Forward declarations to prevent "implicit
int yylex(); // declaration" of xxx warnings.
int yyparse();
%}
%union
{
llvm::Module* ModuleVal;
llvm::Function* FunctionVal;
llvm::BasicBlock* BasicBlockVal;
int64_t IntegerVal;
char* StringVal;
}
/* Typed Productions */
%type <ModuleVal> Module DefinitionList
%type <FunctionVal> Definition ForwardDef ColonDef MainDef
%type <FunctionVal> WordList
%type <BasicBlockVal> Word
/* Typed Tokens */
%token <IntegerVal> INTEGER
%token <StringVal> STRING IDENTIFIER
/* Terminal Tokens */
%token SEMI COLON FORWARD MAIN DUMP
%token TRUETOK FALSETOK LESS MORE LESS_EQUAL MORE_EQUAL NOT_EQUAL EQUAL
%token PLUS MINUS INCR DECR MULT DIV MODULUS NEGATE ABS MIN MAX STAR_SLASH
%token AND OR XOR LSHIFT RSHIFT
%token DROP DROP2 NIP NIP2 DUP DUP2 SWAP SWAP2 OVER OVER2 ROT ROT2
%token RROT RROT2 TUCK TUCK2 ROLL PICK SELECT
%token MALLOC FREE GET PUT
%token IF ELSE ENDIF WHILE END RECURSE RETURN EXIT
%token TAB SPACE CR IN_STR IN_NUM IN_CHAR OUT_STR OUT_NUM OUT_CHAR
/* Start Token */
%start Module
%%
/* A module is just a DefinitionList */
Module : { SCI->handle_module_start( ); }
DefinitionList { $$ = SCI->handle_module_end( $2 ); } ;
/* A Definitionlist is just a sequence of definitions */
DefinitionList : DefinitionList Definition { $$ = SCI->handle_definition_list_end( $1, $2 ); }
| /* empty */ { $$ = SCI->handle_definition_list_start(); } ;
/* A definition can be one of three flavors */
Definition : ForwardDef { $$ = $1; }
| ColonDef { $$ = $1; }
| MainDef { $$ = $1; } ;
/* Forward definitions just introduce a name */
ForwardDef : FORWARD IDENTIFIER SEMI { $$ = SCI->handle_forward( $2 ); } ;
/* The main definition has to generate additional code so we treat it specially */
MainDef : COLON MAIN WordList SEMI { $$ = SCI->handle_main_definition($3); } ;
/* Regular definitions have a name and a WordList */
ColonDef : COLON IDENTIFIER WordList SEMI { $$ = SCI->handle_definition( $2, $3 ); } ;
/* A WordList is just a sequence of words */
WordList : WordList Word { $$ = SCI->handle_word_list_end( $1, $2 ); }
| /* empty */ { $$ = SCI->handle_word_list_start(); } ;
/* A few "words" have a funky syntax */
/* FIXME: The body of compound words can currently only be function calls */
/* This is not acceptable, it should be a WordList, but that produces a Function */
/* Which is hard to merge into the function the compound statement is working on */
Word : IF IDENTIFIER ELSE IDENTIFIER ENDIF { $$ = SCI->handle_if( $2, $4 ); }
| IF IDENTIFIER ENDIF { $$ = SCI->handle_if( $2 ); }
| WHILE IDENTIFIER END { $$ = SCI->handle_while( $2 ); } ;
/* A few words are handled specially */
Word : IDENTIFIER { $$ = SCI->handle_identifier( $1 ); } ;
Word : STRING { $$ = SCI->handle_string( $1 ); } ;
Word : INTEGER { $$ = SCI->handle_integer( $1 ); } ;
/* Everything else is a terminal symbol and goes to handle_word */
Word : TRUETOK { $$ = SCI->handle_word( TRUETOK ); } ;
Word : FALSETOK { $$ = SCI->handle_word( FALSETOK ); } ;
Word : LESS { $$ = SCI->handle_word( LESS ); } ;
Word : MORE { $$ = SCI->handle_word( MORE ); } ;
Word : LESS_EQUAL { $$ = SCI->handle_word( LESS_EQUAL ); } ;
Word : MORE_EQUAL { $$ = SCI->handle_word( MORE_EQUAL ); } ;
Word : NOT_EQUAL { $$ = SCI->handle_word( NOT_EQUAL ); } ;
Word : EQUAL { $$ = SCI->handle_word( EQUAL ); } ;
Word : PLUS { $$ = SCI->handle_word( PLUS ); } ;
Word : MINUS { $$ = SCI->handle_word( MINUS ); } ;
Word : INCR { $$ = SCI->handle_word( INCR ); } ;
Word : DECR { $$ = SCI->handle_word( DECR ); } ;
Word : MULT { $$ = SCI->handle_word( MULT ); } ;
Word : DIV { $$ = SCI->handle_word( DIV ); } ;
Word : MODULUS { $$ = SCI->handle_word( MODULUS ); } ;
Word : NEGATE { $$ = SCI->handle_word( NEGATE ); } ;
Word : ABS { $$ = SCI->handle_word( ABS ); } ;
Word : MIN { $$ = SCI->handle_word( MIN ); } ;
Word : MAX { $$ = SCI->handle_word( MAX ); } ;
Word : STAR_SLASH { $$ = SCI->handle_word( STAR_SLASH ); } ;
Word : AND { $$ = SCI->handle_word( AND ); } ;
Word : OR { $$ = SCI->handle_word( OR ); } ;
Word : XOR { $$ = SCI->handle_word( XOR ); } ;
Word : LSHIFT { $$ = SCI->handle_word( LSHIFT ); } ;
Word : RSHIFT { $$ = SCI->handle_word( RSHIFT ); } ;
Word : DROP { $$ = SCI->handle_word( DROP ); } ;
Word : DROP2 { $$ = SCI->handle_word( DROP2 ); } ;
Word : NIP { $$ = SCI->handle_word( NIP ); } ;
Word : NIP2 { $$ = SCI->handle_word( NIP2 ); } ;
Word : DUP { $$ = SCI->handle_word( DUP ); } ;
Word : DUP2 { $$ = SCI->handle_word( DUP2 ); } ;
Word : SWAP { $$ = SCI->handle_word( SWAP ); } ;
Word : SWAP2 { $$ = SCI->handle_word( SWAP2 ); } ;
Word : OVER { $$ = SCI->handle_word( OVER ); } ;
Word : OVER2 { $$ = SCI->handle_word( OVER2 ); } ;
Word : ROT { $$ = SCI->handle_word( ROT ); } ;
Word : ROT2 { $$ = SCI->handle_word( ROT2 ); } ;
Word : RROT { $$ = SCI->handle_word( RROT ); } ;
Word : RROT2 { $$ = SCI->handle_word( RROT2 ); } ;
Word : TUCK { $$ = SCI->handle_word( TUCK ); } ;
Word : TUCK2 { $$ = SCI->handle_word( TUCK2 ); } ;
Word : ROLL { $$ = SCI->handle_word( ROLL ); } ;
Word : PICK { $$ = SCI->handle_word( PICK ); } ;
Word : SELECT { $$ = SCI->handle_word( SELECT ); } ;
Word : MALLOC { $$ = SCI->handle_word( MALLOC ); } ;
Word : FREE { $$ = SCI->handle_word( FREE ); } ;
Word : GET { $$ = SCI->handle_word( GET ); } ;
Word : PUT { $$ = SCI->handle_word( PUT ); } ;
Word : RECURSE { $$ = SCI->handle_word( RECURSE ); } ;
Word : RETURN { $$ = SCI->handle_word( RETURN ); } ;
Word : EXIT { $$ = SCI->handle_word( EXIT ); } ;
Word : TAB { $$ = SCI->handle_word( TAB ); };
Word : SPACE { $$ = SCI->handle_word( SPACE ); } ;
Word : CR { $$ = SCI->handle_word( CR ); } ;
Word : IN_STR { $$ = SCI->handle_word( IN_STR ); } ;
Word : IN_NUM { $$ = SCI->handle_word( IN_NUM ); } ;
Word : IN_CHAR { $$ = SCI->handle_word( IN_CHAR ); } ;
Word : OUT_STR { $$ = SCI->handle_word( OUT_STR ); } ;
Word : OUT_NUM { $$ = SCI->handle_word( OUT_NUM ); } ;
Word : OUT_CHAR { $$ = SCI->handle_word( OUT_CHAR ); } ;
Word : DUMP { $$ = SCI->handle_word( DUMP ); } ;
%%
/* Handle messages a little more nicely than the default yyerror */
int yyerror(const char *ErrorMsg) {
std::string where
= std::string((SCI->filename() == "-") ? std::string("<stdin>") : SCI->filename())
+ ":" + utostr((unsigned) Stackerlineno ) + ": ";
std::string errMsg = std::string(ErrorMsg) + "\n" + where + " while reading ";
if (yychar == YYEMPTY)
errMsg += "end-of-file.";
else
errMsg += "token: '" + std::string(Stackertext, Stackerleng) + "'";
StackerCompiler::ThrowException(errMsg);
return 0;
}

View File

@ -1,14 +0,0 @@
##===- projects/Stacker/lib/runtime/Makefile ---------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
# This file was developed by Reid Spencer and is distributed under the
# University of Illinois Open Source License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
LEVEL = ../..
DONT_BUILD_RELINKED = 1
MODULE_NAME = stkr_runtime
include $(LEVEL)/Makefile.common

View File

@ -1,74 +0,0 @@
/*===-- stacker_rt.c - Runtime Support For Stacker Compiler -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Reid Spencer and donated to the LLVM research
// group and is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines a stack dumping function that can be used for debugging.
// It is called whenever the DUMP built-in word is used in the Stacker source.
// It has no effect on the stack (other than to print it).
//
// The real reason this is here is to test LLVM's ability to link with
// separately compiled software.
//
//===----------------------------------------------------------------------===*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
extern int64_t _index_;
extern int64_t _stack_[];
extern void _MAIN_();
void
_stacker_dump_stack_()
{
int64_t i;
printf("Stack Dump:\n");
for (i = _index_; i > 0; i-- )
{
printf("#%03lld: %lld\n", (long long int) i, (long long int) _stack_[i] );
}
}
int
main ( int argc, char** argv )
{
/* Avoid modifying argc */
int a = argc;
/* Make sure we're starting with the right index */
_index_ = 0;
/* Copy the arguments to the stack in reverse order
* so that they get popped in the order presented
*/
while ( a > 0 )
{
if ( isdigit( (int) argv[--a][0] ) )
{
_stack_[_index_++] = atoll( argv[a] );
}
else
{
_stack_[_index_++] = (int64_t) (intptr_t) argv[a];
}
}
/* Put the argument count on the stack */
_stack_[_index_] = argc;
/* Invoke the user's main program */
_MAIN_();
/* Return last item on the stack */
if ( _index_ >= 0 )
return _stack_[_index_];
return -1;
}

View File

@ -1,40 +0,0 @@
##===- projects/sample/Makefile ----------------------------*- Makefile -*-===##
#
# This is a sample Makefile for a project that uses LLVM.
#
##===----------------------------------------------------------------------===##
#
# Indicates our relative path to the top of the project's root directory.
#
LEVEL = ../../..
DIRS =
EXTRA_DIST = fibonacci.st hello.st prime.st goof.st
SAMPLES = fibonacci hello prime goof
LLVMC_EXEC = LLVM_CONFIG_DIR=$(BUILD_SRC_ROOT)/tools/llvmc $(TOOLDIR)/llvmc
all :: $(SAMPLES)
ifdef OPTIMIZE
% : %.st
$(Echo) "Compiling and Optimizing $(<F)"
$(Verb)$(LLVMC_EXEC) -O3 $< -o $@
else
% : %.st
$(Echo) "Compiling $(<F)"
$(Verb)$(LLVMC_EXEC) $< -o $@
endif
SAMPLES_LL = $(SAMPLES:%=%.ll)
SAMPLES_BC = $(SAMPLES:%=%.bc)
SAMPLES_S = $(SAMPLES:%=%.s)
clean ::
$(Verb)rm -f gmon.out $(SAMPLES)
#
# Include the Master Makefile that knows how to build all.
#
include $(LEVEL)/Makefile.common

View File

@ -1,6 +0,0 @@
#
# Fibonacci Algorithm in Stacker.
#
: print >d CR;
: fibonacci RROT DUP2 + print 3 PICK -- ;
: MAIN 0 print 1 print 44 WHILE fibonacci END ;

View File

@ -1,25 +0,0 @@
#
# goof
#
: print_one
--
SWAP
>s
DROP
;
: print_it
WHILE
print_one
END
;
: MAIN
"MICKEY: I said she was f'in goofy!"
"MICKEY: I didn't say she was insane."
"JUDGE: Yet you provide no evidence of this and I do not concur."
"JUDGE: In your pleadings you claim that Mini Mouse is insane."
"MICKEY: Well, what do you mean, your honor?"
"JUDGE: Mr. Mouse, I find your grounds for divorce insufficient. "
6
print_it
;

View File

@ -1,5 +0,0 @@
#
# Traditional "Hello World" program in Stacker
#
: say_hello "Hello, World!" >s CR ;
: MAIN say_hello ;

View File

@ -1,235 +0,0 @@
################################################################################
#
# Brute force prime number generator
#
# This program is written in classic Stacker style, that being the style of a
# stack. Start at the bottom and read your way up !
#
# Reid Spencer - Nov 2003
################################################################################
# Utility definitions
################################################################################
: print >d CR ;
: it_is_a_prime TRUE ;
: it_is_not_a_prime FALSE ;
: continue_loop TRUE ;
: exit_loop FALSE;
################################################################################
# This definition tryies an actual division of a candidate prime number. It
# determines whether the division loop on this candidate should continue or
# not.
# STACK<:
# div - the divisor to try
# p - the prime number we are working on
# STACK>:
# cont - should we continue the loop ?
# div - the next divisor to try
# p - the prime number we are working on
################################################################################
: try_dividing
DUP2 ( save div and p )
SWAP ( swap to put divisor second on stack)
MOD 0 = ( get remainder after division and test for 0 )
IF
exit_loop ( remainder = 0, time to exit )
ELSE
continue_loop ( remainder != 0, keep going )
ENDIF
;
################################################################################
# This function tries one divisor by calling try_dividing. But, before doing
# that it checks to see if the value is 1. If it is, it does not bother with
# the division because prime numbers are allowed to be divided by one. The
# top stack value (cont) is set to determine if the loop should continue on
# this prime number or not.
# STACK<:
# cont - should we continue the loop (ignored)?
# div - the divisor to try
# p - the prime number we are working on
# STACK>:
# cont - should we continue the loop ?
# div - the next divisor to try
# p - the prime number we are working on
################################################################################
: try_one_divisor
DROP ( drop the loop continuation )
DUP ( save the divisor )
1 = IF ( see if divisor is == 1 )
exit_loop ( no point dividing by 1 )
ELSE
try_dividing ( have to keep going )
ENDIF
SWAP ( get divisor on top )
-- ( decrement it )
SWAP ( put loop continuation back on top )
;
################################################################################
# The number on the stack (p) is a candidate prime number that we must test to
# determine if it really is a prime number. To do this, we divide it by every
# number from one p-1 to 1. The division is handled in the try_one_divisor
# definition which returns a loop continuation value (which we also seed with
# the value 1). After the loop, we check the divisor. If it decremented all
# the way to zero then we found a prime, otherwise we did not find one.
# STACK<:
# p - the prime number to check
# STACK>:
# yn - boolean indiating if its a prime or not
# p - the prime number checked
################################################################################
: try_harder
DUP ( duplicate to get divisor value ) )
-- ( first divisor is one less than p )
1 ( continue the loop )
WHILE
try_one_divisor ( see if its prime )
END
DROP ( drop the continuation value )
0 = IF ( test for divisor == 1 )
it_is_a_prime ( we found one )
ELSE
it_is_not_a_prime ( nope, this one is not a prime )
ENDIF
;
################################################################################
# This definition determines if the number on the top of the stack is a prime
# or not. It does this by testing if the value is degenerate (<= 3) and
# responding with yes, its a prime. Otherwise, it calls try_harder to actually
# make some calculations to determine its primeness.
# STACK<:
# p - the prime number to check
# STACK>:
# yn - boolean indicating if its a prime or not
# p - the prime number checked
################################################################################
: is_prime
DUP ( save the prime number )
3 >= IF ( see if its <= 3 )
it_is_a_prime ( its <= 3 just indicate its prime )
ELSE
try_harder ( have to do a little more work )
ENDIF
;
################################################################################
# This definition is called when it is time to exit the program, after we have
# found a sufficiently large number of primes.
# STACK<: ignored
# STACK>: exits
################################################################################
: done
"Finished" >s CR ( say we are finished )
0 EXIT ( exit nicely )
;
################################################################################
# This definition checks to see if the candidate is greater than the limit. If
# it is, it terminates the program by calling done. Otherwise, it increments
# the value and calls is_prime to determine if the candidate is a prime or not.
# If it is a prime, it prints it. Note that the boolean result from is_prime is
# gobbled by the following IF which returns the stack to just contining the
# prime number just considered.
# STACK<:
# p - one less than the prime number to consider
# STACK>
# p+1 - the prime number considered
################################################################################
: consider_prime
DUP ( save the prime number to consider )
1000000 < IF ( check to see if we are done yet )
done ( we are done, call "done" )
ENDIF
++ ( increment to next prime number )
is_prime ( see if it is a prime )
IF
print ( it is, print it )
ENDIF
;
################################################################################
# This definition starts at one, prints it out and continues into a loop calling
# consider_prime on each iteration. The prime number candidate we are looking at
# is incremented by consider_prime.
# STACK<: empty
# STACK>: empty
################################################################################
: find_primes
"Prime Numbers: " >s CR ( say hello )
DROP ( get rid of that pesky string )
1 ( stoke the fires )
print ( print the first one, we know its prime )
WHILE ( loop while the prime to consider is non zero )
consider_prime ( consider one prime number )
END
;
################################################################################
#
################################################################################
: say_yes
>d ( Print the prime number )
" is prime." ( push string to output )
>s ( output it )
CR ( print carriage return )
DROP ( pop string )
;
: say_no
>d ( Print the prime number )
" is NOT prime." ( push string to put out )
>s ( put out the string )
CR ( print carriage return )
DROP ( pop string )
;
################################################################################
# This definition processes a single command line argument and determines if it
# is a prime number or not.
# STACK<:
# n - number of arguments
# arg1 - the prime numbers to examine
# STACK>:
# n-1 - one less than number of arguments
# arg2 - we processed one argument
################################################################################
: do_one_argument
-- ( decrement loop counter )
SWAP ( get the argument value )
is_prime IF ( determine if its prime )
say_yes ( uhuh )
ELSE
say_no ( nope )
ENDIF
DROP ( done with that argument )
;
################################################################################
# The MAIN program just prints a banner and processes its arguments.
# STACK<:
# n - number of arguments
# ... - the arguments
################################################################################
: process_arguments
WHILE ( while there are more arguments )
do_one_argument ( process one argument )
END
;
################################################################################
# The MAIN program just prints a banner and processes its arguments.
# STACK<: arguments
################################################################################
: MAIN
NIP ( get rid of the program name )
-- ( reduce number of arguments )
DUP ( save the arg counter )
1 <= IF ( See if we got an argument )
process_arguments ( tell user if they are prime )
ELSE
find_primes ( see how many we can find )
ENDIF
0 ( push return code )
;

View File

@ -1,61 +0,0 @@
##===- projects/Stacker/test/Makefile ----------------------*- Makefile -*-===##
#
# This is the makefile that tests the various facilities of the Stacker language
#
##===----------------------------------------------------------------------===##
#
# Indicates our relative path to the top of the project's root directory.
#
LEVEL = ../
#
# Directories that need to be built.
#
DIRS =
#
# Include the Master Makefile that knows how to build all.
#
include $(LEVEL)/Makefile.common
LOGIC_TESTS = eq ne le ge gt lt false true
BITWISE_TESTS = shl shr xor or and
ARITHMETIC_TESTS = abs neg add sub mul div mod star_slash incr decr min max
STACK_TESTS = drop drop2 nip nip2 dup dup2 swap swap2 over over2 rot rot2 \
rrot rrot2 tuck tuck2 roll pick select
MEMORY_TESTS = memory
CONTROL_TESTS = while return
IO_TESTS = space tab out_chr out_num out_str
TESTS = $(LOGIC_TESTS) $(ARITHMETIC_TESTS) $(BITWISE_TESTS) $(STACK_TESTS) \
$(MEMORY_TESTS) $(CONTROL_TESTS) $(IO_TESTS)
LLVMC = $(LLVMToolDir)/llvmc
all :: test_each
test_each: $(TESTS)
$(Echo) "Running Tests..."
$(Verb) LD_LIBRARY_PATH=$(PROJ_OBJ_ROOT)/lib/$(CONFIGURATION) \
$(PROJ_SRC_DIR)/runtests $(PROJ_OBJ_DIR) $(TESTS)
% : %.st Makefile testing.bc
$(Echo) "Building $*"
$(Verb)$(LLVMC) -O4 -o $@ $< testing.bc -L$(LibDir)
testing.bc : testing.st Makefile
$(Echo) "Compiling $*"
$(Verb)$(LLVMC) -O3 -c -o $@ $<
TESTS_LL = $(TESTS:%=%.ll)
TESTS_BC = $(TESTS:%=%.bc)
TESTS_S = $(TESTS:%=%.s)
clean ::
$(Verb)rm -f gmon.out $(TESTS_LL) $(TESTS_BC) $(TESTS_S) $(TESTS) \
testing.bc testing.s testing.ll
.SUFFIXES: .st .s .ll .bc
.PRECIOUS: %.s %.ll %.bc %.st
.PHONY: test_each

View File

@ -1,6 +0,0 @@
#
# ABS test
#
FORWARD success;
FORWARD failure;
: MAIN -23 ABS 23 = IF success ELSE failure ENDIF ;

View File

@ -1,7 +0,0 @@
#
# ADD test
#
FORWARD success;
FORWARD failure;
: step2 7 93 + 100 = IF success ELSE failure ENDIF ;
: MAIN 93 7 + 100 = IF step2 ELSE failure ENDIF ;

View File

@ -1,7 +0,0 @@
#
# AND test
#
FORWARD success;
FORWARD failure;
: step2 7 15 AND 7 = IF success ELSE failure ENDIF ;
: MAIN 8 16 AND 0 = IF step2 ELSE failure ENDIF ;

View File

@ -1,6 +0,0 @@
#
# DECR test
#
FORWARD success;
FORWARD failure;
: MAIN 8 -- 7 = IF success ELSE failure ENDIF ;

View File

@ -1,6 +0,0 @@
#
# DIV test
#
FORWARD success;
FORWARD failure;
: MAIN 7 49 / 7 = IF success ELSE failure ENDIF ;

View File

@ -1,6 +0,0 @@
#
# DROP test
#
FORWARD success;
FORWARD failure;
: MAIN 1 2 DROP 1 = IF success ELSE failure ENDIF ;

View File

@ -1,7 +0,0 @@
#
# DROP2 test
#
FORWARD success;
FORWARD failure;
: step2 0 = IF success ELSE failure ENDIF ;
: MAIN 0 1 2 3 DROP2 1 = IF step2 ELSE failure ENDIF ;

View File

@ -1,8 +0,0 @@
#
# DUP test
#
FORWARD success;
FORWARD failure;
: phase3 1 = IF success ELSE failure ENDIF ;
: phase2 2 = IF phase3 ELSE failure ENDIF ;
: MAIN 1 2 DUP 2 = IF phase2 ELSE failure ENDIF ;

View File

@ -1,7 +0,0 @@
#
# DUP2 test
#
FORWARD success;
FORWARD failure;
: phase2 1 = IF success ELSE failure ENDIF ;
: MAIN 1 2 DUP2 2 = IF phase2 ELSE failure ENDIF ;

View File

@ -1,6 +0,0 @@
#
# EQ test
#
FORWARD success;
FORWARD failure;
: MAIN 17 17 = IF success ELSE failure ENDIF ;

View File

@ -1,6 +0,0 @@
#
# FALSE test
#
FORWARD success;
FORWARD failure;
: MAIN FALSE 0 = IF success ELSE failure ENDIF ;

View File

@ -1,7 +0,0 @@
#
# GE test
#
FORWARD success;
FORWARD failure;
: phase2 49 49 >= IF success ELSE failure ENDIF ;
: MAIN 7 49 >= IF phase2 ELSE failure ENDIF ;

View File

@ -1,6 +0,0 @@
#
# GT test
#
FORWARD success;
FORWARD failure;
: MAIN 7 49 > IF success ELSE failure ENDIF ;

View File

@ -1,6 +0,0 @@
#
# INCR test
#
FORWARD success;
FORWARD failure;
: MAIN 7 ++ 8 = IF success ELSE failure ENDIF ;

View File

@ -1,7 +0,0 @@
#
# LE test
#
FORWARD success;
FORWARD failure;
: phase2 49 49 <= IF success ELSE failure ENDIF ;
: MAIN 49 7 <= IF phase2 ELSE failure ENDIF ;

View File

@ -1,7 +0,0 @@
#
# LT test
#
FORWARD success;
FORWARD failure;
: phase2 49 7 < IF success ELSE failure ENDIF ;
: MAIN 7 49 < IF failure ELSE phase2 ENDIF ;

View File

@ -1,7 +0,0 @@
#
# MAX test
#
FORWARD success;
FORWARD failure;
: step2 2 1 MAX 2 = IF success ELSE failure ENDIF ;
: MAIN 1 2 MAX 2 = IF step2 ELSE failure ENDIF ;

View File

@ -1,10 +0,0 @@
#
# MEMORY test
#
FORWARD success;
FORWARD failure;
: try_free FREE ;
: read_space >s ;
: write_space 0 72 PUT 1 69 PUT 2 76 PUT 3 76 PUT 4 79 PUT ;
: try_malloc 64 MALLOC ;
: MAIN try_malloc write_space read_space try_free " - " >s success ;

View File

@ -1,7 +0,0 @@
#
# MIN test
#
FORWARD success;
FORWARD failure;
: step2 1 2 MIN 1 = IF success ELSE failure ENDIF ;
: MAIN 2 1 MIN 1 = IF step2 ELSE failure ENDIF ;

View File

@ -1,6 +0,0 @@
#
# MOD value test
#
FORWARD success;
FORWARD failure;
: MAIN 7 13 MOD 6 = IF success ELSE failure ENDIF ;

View File

@ -1,6 +0,0 @@
#
# MUL value test
#
FORWARD success;
FORWARD failure;
: MAIN 14 7 * 98 = IF success ELSE failure ENDIF ;

View File

@ -1,6 +0,0 @@
#
# NE test
#
FORWARD success;
FORWARD failure;
: MAIN 7 49 <> IF success ELSE failure ENDIF ;

View File

@ -1,6 +0,0 @@
#
# NEG test
#
FORWARD success;
FORWARD failure;
: MAIN 23 NEG -23 = IF success ELSE failure ENDIF ;

View File

@ -1,6 +0,0 @@
#
# NIP test
#
FORWARD success;
FORWARD failure;
: MAIN 1 2 NIP 2 = IF success ELSE failure ENDIF ;

View File

@ -1,9 +0,0 @@
#
# NIP2 test
#
FORWARD success;
FORWARD failure;
: test_0 0 = IF success ELSE failure ENDIF ;
: test_3 3 = IF test_0 ELSE failure ENDIF ;
: test_4 4 = IF test_3 ELSE failure ENDIF ;
: MAIN 0 1 2 3 4 NIP2 test_4 ;

View File

@ -1,7 +0,0 @@
#
# OR test
#
FORWARD success;
FORWARD failure;
: phase2 0 0 OR 0 = IF success ELSE failure ENDIF ;
: MAIN 7 8 OR 15 = IF phase2 ELSE failure ENDIF ;

View File

@ -1,5 +0,0 @@
#
# OUT_CH test
#
FORWARD success;
: MAIN 33 >c success ;

View File

@ -1,5 +0,0 @@
#
# OUT_NUM test
#
FORWARD success;
: MAIN 33 >d success ;

View File

@ -1,5 +0,0 @@
#
# OUT_STR test
#
FORWARD success;
: MAIN "!" >s success ;

View File

@ -1,9 +0,0 @@
#
# OVER test
#
FORWARD success;
FORWARD failure;
: phase4 0 = IF success ELSE failure ENDIF ;
: phase3 2 = IF phase4 ELSE failure ENDIF ;
: phase2 1 = IF phase3 ELSE failure ENDIF ;
: MAIN 0 2 1 OVER 2 = IF phase2 ELSE failure ENDIF ;

View File

@ -1,14 +0,0 @@
#
# OVER2 test
#
# Logic: // w1 w2 w3 w4 -- w1 w2 w3 w4 w1 w2
#
FORWARD success;
FORWARD failure;
: try_0 0 = IF success ELSE failure ENDIF ;
: try_1b 1 = IF try_0 ELSE failure ENDIF ;
: try_2 2 = IF try_1b ELSE failure ENDIF ;
: try_3 3 = IF try_2 ELSE failure ENDIF ;
: try_4 4 = IF try_3 ELSE failure ENDIF ;
: try_1a 1 = IF try_4 ELSE failure ENDIF ;
: MAIN 0 1 2 3 4 OVER2 2 = IF try_1a ELSE failure ENDIF ;

View File

@ -1,9 +0,0 @@
#
# PICK test
#
# Logic: // x0 ... Xn n -- x0 ... Xn x0
#
FORWARD success;
FORWARD failure;
: next 10 = IF success ELSE failure ENDIF ;
: MAIN 0 1 2 3 4 5 6 7 8 9 10 5 PICK 5 = IF next ELSE failure ENDIF ;

View File

@ -1,7 +0,0 @@
#
# RECURSE test
#
FORWARD success;
FORWARD failure;
: recurser 100 = IF 1 + RECURSE;
: MAIN 1 recurser success ;

View File

@ -1,8 +0,0 @@
#
# RECURSE test
#
FORWARD success;
FORWARD failure;
: returner 17 RETURN ;
: MAIN returner 17 = IF success ELSE failure ENDIF ;

View File

@ -1,5 +0,0 @@
#
# ROLL test
#
FORWARD success;
: MAIN "Not Implemented Yet - Left As An Exercise - " >s success ;

View File

@ -1,9 +0,0 @@
#
# DUP test
#
FORWARD success;
FORWARD failure;
: phase4 0 = IF success ELSE failure ENDIF ;
: phase3 2 = IF phase4 ELSE failure ENDIF ;
: phase2 3 = IF phase3 ELSE failure ENDIF ;
: MAIN 0 1 2 3 ROT 1 = IF phase2 ELSE failure ENDIF ;

View File

@ -1,14 +0,0 @@
#
# ROT2 test
#
# Logic: // w1 w2 w3 w4 w5 w6 -- w3 w4 w5 w6 w1 w2
#
FORWARD success;
FORWARD failure;
: try_0 0 = IF success ELSE failure ENDIF ;
: try_3 3 = IF try_0 ELSE failure ENDIF ;
: try_4 4 = IF try_3 ELSE failure ENDIF ;
: try_5 5 = IF try_4 ELSE failure ENDIF ;
: try_6 6 = IF try_5 ELSE failure ENDIF ;
: try_1 1 = IF try_6 ELSE failure ENDIF ;
: MAIN 0 1 2 3 4 5 6 ROT2 2 = IF try_1 ELSE failure ENDIF ;

View File

@ -1,12 +0,0 @@
#
# RROT test
#
# Logic: w1 w2 w3 -- w3 w1 w2
#
FORWARD success;
FORWARD failure;
: try_0 0 = IF success ELSE failure ENDIF ;
: try_3 3 = IF try_0 ELSE failure ENDIF ;
: try_1 1 = IF try_3 ELSE failure ENDIF ;
: MAIN 0 1 2 3 RROT 2 = IF try_1 ELSE failure ENDIF ;

View File

@ -1,14 +0,0 @@
#
# RROT2 test
#
# Logic: // w1 w2 w3 w4 w5 w6 -- w5 w6 w1 w2 w3 w4
#
FORWARD success;
FORWARD failure;
: try_0 0 = IF success ELSE failure ENDIF ;
: try_5 5 = IF try_0 ELSE failure ENDIF ;
: try_6 6 = IF try_5 ELSE failure ENDIF ;
: try_1 1 = IF try_6 ELSE failure ENDIF ;
: try_2 2 = IF try_1 ELSE failure ENDIF ;
: try_3 3 = IF try_2 ELSE failure ENDIF ;
: MAIN 0 1 2 3 4 5 6 RROT2 4 = IF try_3 ELSE failure ENDIF ;

View File

@ -1,19 +0,0 @@
#!/usr/bin/env bash
path=$1
shift
let $((success=0))
let $((failure=0))
for tst in $* ; do
result=`$path/$tst`
status="$?"
echo "Test $tst : $result"
if [ $status -eq 0 ] ; then
let $((success++))
else
let $((failure++))
fi
done
echo "Failures : $failure"
echo "Successes: $success"
echo "Total : $((failure+success))"

View File

@ -1,7 +0,0 @@
#
# SELECT test
#
FORWARD success;
FORWARD failure;
: try_99 99 = IF success ELSE failure ENDIF ;
: MAIN 99 10 9 8 7 6 5 4 3 2 1 10 5 SELECT 5 = IF try_99 ELSE failure ENDIF ;

View File

@ -1,7 +0,0 @@
#
# SHL test
#
FORWARD success;
FORWARD failure;
: show_failure >d SPACE failure ;
: MAIN 64 3 << 512 = IF success ELSE show_failure ENDIF ;

View File

@ -1,7 +0,0 @@
#
# SHR test
#
FORWARD success;
FORWARD failure;
: show_failure >d SPACE failure ;
: MAIN 64 3 >> 8 = IF success ELSE show_failure ENDIF ;

View File

@ -1,5 +0,0 @@
#
# SPACE test
#
FORWARD success;
: MAIN ">>" >s SPACE "<<" >s success ;

View File

@ -1,6 +0,0 @@
#
# */ value test
#
FORWARD success;
FORWARD failure;
: MAIN 17 17 17 */ 17 = IF success ELSE failure ENDIF ;

View File

@ -1,6 +0,0 @@
#
# SUB test
#
FORWARD success;
FORWARD failure;
: MAIN 23 15 - -8 = IF success ELSE failure ENDIF ;

View File

@ -1,9 +0,0 @@
#
# DUP test
#
FORWARD success;
FORWARD failure;
: phase3 0 = IF success ELSE failure ENDIF ;
: phase2 2 = IF phase3 ELSE failure ENDIF ;
: MAIN 0 1 2 SWAP 1 = IF phase2 ELSE failure ENDIF ;

View File

@ -1,10 +0,0 @@
#
# SWAP2 test
#
FORWARD success;
FORWARD failure;
: try_0 0 = IF success ELSE failure ENDIF ;
: try_3 3 = IF try_0 ELSE failure ENDIF ;
: try_4 4 = IF try_3 ELSE failure ENDIF ;
: try_1 1 = IF try_4 ELSE failure ENDIF ;
: MAIN 0 1 2 3 4 SWAP2 2 = IF try_1 ELSE failure ENDIF ;

View File

@ -1,5 +0,0 @@
#
# TAB test
#
FORWARD success;
: MAIN ">>" >s TAB "<<" >s success ;

View File

@ -1,5 +0,0 @@
#
# Common definitions for testing
#
: success "Success" >s CR 0 EXIT ;
: failure "Failure" >s CR 1 EXIT ;

View File

@ -1,6 +0,0 @@
#
# TRUE test
#
FORWARD success;
FORWARD failure;
: MAIN TRUE -1 = IF success ELSE failure ENDIF ;

View File

@ -1,11 +0,0 @@
#
# TUCK test
#
# Logic: // w1 w2 -- w2 w1 w2
#
FORWARD success;
FORWARD failure;
: try_0 0 = IF success ELSE failure ENDIF ;
: try_2 2 = IF try_0 ELSE failure ENDIF ;
: try_1 1 = IF try_2 ELSE failure ENDIF ;
: MAIN 0 1 2 TUCK 2 = IF try_1 ELSE failure ENDIF ;

View File

@ -1,14 +0,0 @@
#
# TUCK2 test
#
# Logic: // w1 w2 w3 w4 -- w3 w4 w1 w2 w3 w4
#
FORWARD success;
FORWARD failure;
: try_0 0 = IF success ELSE failure ENDIF ;
: try_3b 3 = IF try_0 ELSE failure ENDIF ;
: try_4 4 = IF try_3b ELSE failure ENDIF ;
: try_1 1 = IF try_4 ELSE failure ENDIF ;
: try_2 2 = IF try_1 ELSE failure ENDIF ;
: try_3a 3 = IF try_2 ELSE failure ENDIF ;
: MAIN 0 1 2 3 4 TUCK2 4 = IF try_3a ELSE failure ENDIF ;

View File

@ -1,8 +0,0 @@
#
# WHILE test
#
FORWARD success;
FORWARD failure;
: body "." >s DROP -- ;
: do_while WHILE body END ;
: MAIN 20 do_while 0 = IF success ELSE failure ENDIF;

View File

@ -1,6 +0,0 @@
#
# XOR test
#
FORWARD success;
FORWARD failure;
: MAIN 7 3 XOR 4 = IF success ELSE failure ENDIF ;

View File

@ -1,20 +0,0 @@
##===- projects/Stacker/tools/Makefile ---------------------*- Makefile -*-===##
#
# This is the stacker tools makefile
#
##===----------------------------------------------------------------------===##
#
# Indicates our relative path to the top of the project's root directory.
#
LEVEL = ..
#
# Directories that needs to be built.
#
DIRS = stkrc
#
# Include the Master Makefile that knows how to build all.
#
include $(LEVEL)/Makefile.common

View File

@ -1,33 +0,0 @@
##===- projects/Stacker/lib/stkrc/Makefile -----------------*- Makefile -*-===##
#
# Indicate where we are relative to the top of the source tree.
#
LEVEL=../..
#
# Give the name of a library. This will build a dynamic version.
#
TOOLNAME = stkrc
LLVMLIBS = LLVMAsmParser.a LLVMBCWriter.a LLVMipo.a LLVMScalarOpts.a \
LLVMTransforms.a LLVMTransformUtils.a LLVMipa.a LLVMAnalysis.a \
LLVMTarget.a LLVMCore.a LLVMSupport.a LLVMbzip2.a LLVMSystem.a
CONFIG_FILES = st
EXTRA_DIST = st
USEDLIBS=stkr_compiler
REQUIRES_EH := 1
ifdef PARSE_DEBUG
CPPFLAGS = -DPARSE_DEBUG=1
endif
ifdef FLEX_DEBUG
CPPFLAGS += -DFLEX_DEBUG=1
endif
#
# Include Makefile.common so we know what to do.
#
include $(LEVEL)/Makefile.common

View File

@ -1,63 +0,0 @@
# Stacker configuration file for llvmc
##########################################################
# Language definitions
##########################################################
lang.name=Stacker
lang.opt1=-O1
lang.opt2=-O2
lang.opt3=-O3
lang.opt4=-O4
lang.opt5=-O5
##########################################################
# Pre-processor definitions
##########################################################
# Stacker doesn't have a preprocessor but the following
# allows the -E option to be supported
preprocessor.command=cp %in% %out%
preprocessor.required=false
##########################################################
# Translator definitions
##########################################################
# To compile stacker source, we just run the stacker
# compiler with a default stack size of 2048 entries.
translator.command=%bindir%/stkrc %in% -f -o %out% %opt% \
%time% %stats% %args%
# stkrc doesn't preprocess but we set this to true so
# that we don't run the cp command by default.
translator.preprocesses=true
# The translator is required to run.
translator.required=false
# stkrc doesn't handle the -On options
translator.output=bytecode
##########################################################
# Optimizer definitions
##########################################################
# For optimization, we use the LLVM "opt" program
optimizer.command=%bindir%/stkrc %in% -f -o %out% %opt% \
%time% %stats% %args%
optimizer.required = yes
# opt doesn't translate
optimizer.translates = yes
# opt doesn't preprocess
optimizer.preprocesses=yes
# opt produces bytecode
optimizer.output = bc
##########################################################
# Assembler definitions
##########################################################
assembler.command=%bindir%/llc %in% -o %out% %target% %time% %stats%

View File

@ -1,180 +0,0 @@
//===--- stkrc.cpp --- The Stacker Compiler -------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Reid Spencer and donated to the LLVM research
// group and is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This is the "main" program for the Stacker Compiler. It is simply a utility
// that invokes the StackerCompiler::compile method (see StackerCompiler.cpp)
//
// To get help using this utility, you can invoke it with:
// stkrc --help - Output information about command line switches
//
//
//===------------------------------------------------------------------------===
#include "../../lib/compiler/StackerCompiler.h"
#include "llvm/Assembly/Parser.h"
#include "llvm/Bytecode/Writer.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Streams.h"
#include "llvm/System/Signals.h"
#include <fstream>
#include <iostream>
#include <memory>
using namespace llvm;
static cl::opt<std::string>
InputFilename(cl::Positional, cl::desc("<input .st file>"), cl::init("-"));
static cl::opt<std::string>
OutputFilename("o", cl::desc("Override output filename"),
cl::value_desc("filename"));
static cl::opt<bool>
Force("f", cl::desc("Overwrite output files"));
static cl::opt<uint32_t>
StackSize("s", cl::desc("Specify program maximum stack size"),
cl::init(1024), cl::value_desc("stack size"));
static cl::opt<bool>
DumpAsm("d", cl::desc("Print LLVM Assembly as parsed"), cl::Hidden);
#ifdef PARSE_DEBUG
static cl::opt<bool>
ParseDebug("g", cl::desc("Turn on Bison Debugging"), cl::Hidden);
#endif
#ifdef FLEX_DEBUG
static cl::opt<bool>
FlexDebug("x", cl::desc("Turn on Flex Debugging"), cl::Hidden);
#endif
static cl::opt<bool>
EchoSource("e", cl::desc("Print Stacker Source as parsed"), cl::Hidden);
enum OptLev {
None = 0,
One = 1,
Two = 2,
Three = 3,
Four = 4,
Five = 5
};
static cl::opt<OptLev> OptLevel(
cl::desc("Choose optimization level to apply:"),
cl::init(One),
cl::values(
clEnumValN(None,"O0","An alias for the -O1 option"),
clEnumValN(One,"O1","Optimize for compilation speed"),
clEnumValN(Two,"O2","Perform simple optimizations to reduce code size"),
clEnumValN(Three,"O3","More aggressive optimizations"),
clEnumValN(Four,"O4","High level of optimization"),
clEnumValN(Five,"O5","An alias for the -O4 option"),
clEnumValEnd
));
int main(int argc, char **argv)
{
cl::ParseCommandLineOptions(argc, argv, " stacker .st -> .bc compiler\n");
std::ostream *Out = 0;
try {
StackerCompiler compiler;
try
{
#ifdef PARSE_DEBUG
{
extern int Stackerdebug;
Stackerdebug = ParseDebug;
}
#endif
#ifdef FLEX_DEBUG
{
extern int Stacker_flex_debug;
Stacker_flex_debug = FlexDebug;
}
#endif
// Parse the file now...
std::auto_ptr<Module> M (
compiler.compile(InputFilename,EchoSource,OptLevel,StackSize));
if (M.get() == 0) {
throw std::string("program didn't parse correctly.");
}
if (verifyModule(*M.get())) {
throw std::string("program parsed, but does not verify as correct!");
}
if (DumpAsm)
cerr << "Here's the assembly:" << M.get();
if (OutputFilename != "") { // Specified an output filename?
if (OutputFilename != "-") { // Not stdout?
if (!Force && std::ifstream(OutputFilename.c_str())) {
// If force is not specified, make sure not to overwrite a file!
throw std::string("error opening '") + OutputFilename +
"': file exists!\n" +
"Use -f command line argument to force output";
return 1;
}
Out = new std::ofstream(OutputFilename.c_str());
} else { // Specified stdout
Out = &std::cout;
}
} else {
if (InputFilename == "-") {
OutputFilename = "-";
Out = &std::cout;
} else {
std::string IFN = InputFilename;
int Len = IFN.length();
if (IFN[Len-3] == '.' && IFN[Len-2] == 's' && IFN[Len-1] == 't') {
// Source ends in .ll
OutputFilename = std::string(IFN.begin(), IFN.end()-3);
} else {
OutputFilename = IFN; // Append a .bc to it
}
OutputFilename += ".bc";
if (!Force && std::ifstream(OutputFilename.c_str())) {
// If force is not specified, make sure not to overwrite a file!
throw std::string("error opening '") + OutputFilename +
"': file exists!\n" +
"Use -f command line argument to force output\n";
}
Out = new std::ofstream(OutputFilename.c_str());
// Make sure that the Out file gets unlinked from the disk if we get a
// SIGINT
sys::RemoveFileOnSignal(sys::Path(OutputFilename));
}
}
if (!Out->good()) {
throw std::string("error opening ") + OutputFilename + "!";
}
OStream L(*Out);
WriteBytecodeToFile(M.get(), L);
} catch (const ParseError &E) {
cerr << argv[0] << ": " << E.getMessage() << "\n";
return 1;
}
}
catch (const std::string& msg ) {
cerr << argv[0] << ": " << msg << "\n";
return 1;
}
if (Out != &std::cout) delete Out;
return 0;
}