Merge from trunk.

This commit is contained in:
David Given 2017-08-06 10:42:16 +02:00
commit fd10cf7ac2
375 changed files with 12604 additions and 4191 deletions

View file

@ -7,5 +7,6 @@ IndentCaseLabels: 'true'
PointerAlignment: Left
TabWidth: '4'
UseTab: ForIndentation
SortIncludes: false
...

View file

@ -1,13 +1,12 @@
matrix:
include:
- os: linux
- os: osx
addons:
apt:
packages:
- ed
- openbios-ppc
- qemu-user
git:
depth: 10

View file

@ -63,7 +63,7 @@ PLATDEP = $(INSDIR)/lib/ack
.NOTPARALLEL:
MAKECMDGOALS ?= +ack
MAKECMDGOALS ?= +ack +tests
BUILD_FILES = $(shell find * -name '*.lua')
ifneq ($(shell which ninja),)
@ -88,6 +88,7 @@ $(BUILDDIR)/build.$(BUILDSYSTEM): first/ackbuilder.lua Makefile $(BUILD_FILES) $
@$(LUA) first/ackbuilder.lua \
first/build.lua build.lua \
--$(BUILDSYSTEM) \
DEFAULT_PLATFORM=$(DEFAULT_PLATFORM) \
OBJDIR=$(OBJDIR) \
BINDIR=$(BINDIR) \
LIBDIR=$(LIBDIR) \
@ -95,6 +96,7 @@ $(BUILDDIR)/build.$(BUILDSYSTEM): first/ackbuilder.lua Makefile $(BUILD_FILES) $
INSDIR=$(INSDIR) \
PLATIND=$(PLATIND) \
PLATDEP=$(PLATDEP) \
PREFIX=$(PREFIX) \
AR=$(AR) \
CC=$(CC) \
> $(BUILDDIR)/build.$(BUILDSYSTEM)

26
README
View file

@ -2,7 +2,7 @@
===================================
© 1987-2005 Vrije Universiteit, Amsterdam
2016-08-02
2017-01-07
INTRODUCTION
@ -19,22 +19,25 @@ probably broken. However, what's there should be sufficient to get things
done and to evaluate how the full 6.1 release should work.
SUPPORT
=======
Languages:
ANSI C, Pascal, Modula 2, Basic. K&R is supported via the ANSI C compiler.
ANSI C, B, Pascal, Modula 2, Basic. K&R is supported via the ANSI C compiler.
Platforms:
pc86 produces bootable floppy disk images for 8086 PCs
linux386 produces ELF executables for PC Linux systems
linux68k produces ELF executables for m68020 Linux systems
linuxppc produces ELF executables for PowerPC Linux systems
cpm produces i80 CP/M .COM files
rpi produces Raspberry Pi GPU binaries
INSTALLATION
============
@ -55,6 +58,11 @@ Requirements:
- (optionally) ninja; if you've got this, this will be autodetected and give
you faster builds.
- (optionally) the qemu suite: if you have this installed, the build system
will detect it automatically and run the test suites for the supported
architectures. Get both the qemu-system-* platform emulators and the qemu-*
userland emulators (only works on Linux).
- about 40MB free in /tmp (or some other temporary directory).
- about 6MB in the target directory.
@ -89,6 +97,7 @@ Instructions:
The ACK should now be ready to use.
USAGE
=====
@ -111,7 +120,8 @@ Some useful options include:
ack figures out which language to use from the file extension:
.c C (ANSI or K&R)
.b Basic
.b the PDP-11 dialect of B
.bas Basic
.mod Modula-2
.ocm Occam 1
.p Pascal
@ -150,11 +160,17 @@ There are some things you should be aware of.
- The ACK uses its own .o format. You won't be able to mix the ACK's object
files and another compiler's.
- When compiling together multiple B source files, you need to do some extra
work to initialise them properly otherwise your program will crash on
startup; see the ack(1) and abmodules(1) man pages.
- The distribution contains *everything*, including the weird, ancient,
archaic stuff that doesn't work any more and never will, such as the int EM
interpreter and the assembler-linkers. Only some of it builds. Look for
build.lua files.
DISCLAIMER
==========
@ -177,6 +193,6 @@ You can find the mailing list on the project's web site:
Please enjoy.
David Given (dtrg on Sourceforge)
David Given (davidgiven on Github)
dg@cowlark.com
2016-08-02
2016-11-26

View file

@ -9,12 +9,17 @@ vars.plats = {
"linux386",
"linux68k",
"linuxppc",
"osx386",
"osxppc",
"qemuppc",
"pc86",
"rpi",
}
vars.plats_with_tests = {
"linux386",
"linuxppc",
"qemuppc",
"pc86",
}
local plat_packages = {}
@ -33,6 +38,7 @@ installable {
"lang/cem/cemcom.ansi+pkg",
"lang/m2/comp+pkg",
"lang/pc/comp+pkg",
"lang/b/compiler+pkg",
"util/ack+pkg",
"util/amisc+pkg",
"util/arch+pkg",
@ -43,8 +49,18 @@ installable {
"examples+pkg",
plat_packages
},
deps = {
test_packages
}
}
normalrule {
name = "tests",
ins = {
"first/testsummary.sh",
test_packages
},
outleaves = {
"stamp"
},
commands = {
"%{ins}"
}
}

View file

@ -6,6 +6,7 @@ local conly = {
local sourcefiles = filenamesof(
"./hilo.b",
"./hilo.bas",
"./hilo.c",
"./hilo.mod",
"./hilo.p",

View file

@ -1,39 +1,108 @@
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$; "!"
buffer[6];
PlayerName[6];
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
/* Taken intact from the B reference manual. */
strcopy(sl ,s2)
{
auto i;
1000 print "See if you can guess my number."
1010 Number% = rnd(1) mod 100
1020 Attempts% = 1
i = 0;
while (lchar(sl, i, char(s2, i)) != '*e')
i++;
}
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
reads()
{
extrn buffer;
putstr("> ");
flush();
getstr(buffer);
}
atoi(s)
{
auto value, sign, i, c;
i = 0;
if (char(s, i) == '-')
{
sign = -1;
i++;
}
else
sign = 1;
value = 0;
while ((c = char(s, i++)) != '*e')
value = value*10 + (c - '0');
return(value * sign);
}
rand()
{
/* Genuinely random; retrieved from random.org */
return(57);
}
game()
{
extrn buffer;
auto Number, Attempts;
auto guess;
printf("See if you can guess my number.*n");
Number = rand() % 100;
Attempts = 1;
while (1)
{
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++;
}
}
main()
{
extrn buffer, PlayerName;
printf("*nHi there! I'm written in B. Before we start, what is your name?*n");
reads();
strcopy(PlayerName, buffer);
printf("*nHello, %s! ", PlayerName);
while (1)
{
game();
printf("*nWould you like another go?*n");
reads();
if ((char(buffer, 0) == 'n') | (char(buffer, 0) == 'N'))
{
printf("*nThanks for playing --- goodbye!*n");
break;
}
printf("*nExcellent! ");
}
return(0);
}

39
examples/hilo.bas Normal file
View file

@ -0,0 +1,39 @@
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

View file

@ -15,6 +15,7 @@
This is a public domain adventure and may not be sold for profit */
#include <stdlib.h>
#include <stdio.h>
#define MOXIE 13
@ -32,7 +33,9 @@ int plato_clone=3;
int blast_door=0;
int killer_count=0;
char get_char()
void character(void);
char get_char(void)
{
char c;
fflush(stdout);
@ -41,7 +44,7 @@ char get_char()
return c;
}
more()
void more(void)
{
printf("---------- More ----------");
#ifdef DEBUG
@ -55,8 +58,7 @@ more()
};
}
new_clone(resume)
int resume;
int new_clone(int resume)
{
printf("\nClone %d just died.\n",clone);
if (++clone>6)
@ -75,15 +77,14 @@ int resume;
}
}
dice_roll(number,faces)
int number, faces;
int dice_roll(int number, int faces)
{
int i,total=0;
for(i=number;i>0;i--) total+= rand()%faces+1;
return total;
}
instructions()
void instructions(void)
{
printf("\n\n\n\nWelcome to Paranoia!\n\n");
printf("HOW TO PLAY:\n\n");
@ -104,7 +105,7 @@ instructions()
printf(" If not, you can try again later.\n");
}
character()
void character(void)
{
printf("===============================================================================\n");
printf("The Character : Philo-R-DMD %d\n", clone);
@ -130,9 +131,7 @@ character()
printf("===============================================================================\n");
}
choose(a,aptr,b,bptr)
int a,b;
char *aptr, *bptr;
int choose(int a, char* aptr, int b, char* bptr)
{
printf("\nSelect \'a\' or \'b\' :\n");
printf(" a - %s.\n b - %s.\n", aptr, bptr);
@ -140,7 +139,7 @@ char *aptr, *bptr;
else return b;
}
page1()
int page1(void)
{
printf(" You wake up face down on the red and pink checked E-Z-Kleen linoleum floor.\n");
printf(" You recognise the pattern, it\'s the type preferred in the internal security\nbriefing cells. When you finally look around you, you see that you are alone\n");
@ -148,7 +147,7 @@ page1()
return 57;
}
page2()
int page2(void)
{
printf("\"Greetings,\" says the kindly Internal Security self incrimination expert who\n");
printf("meets you at the door, \"How are we doing today?\" He offers you a doughnut\n");
@ -166,7 +165,7 @@ page2()
else return new_clone(32);
}
page3()
int page3(void)
{
printf("You walk to the nearest Computer terminal and request more information about\n");
printf("Christmas. The Computer says, \"That is an A-1 ULTRAVIOLET ONLY IMMEDIATE\n");
@ -174,7 +173,7 @@ page3()
return choose(4,"You give your correct clearance",5,"You lie and claim Ultraviolet clearance");
}
page4()
int page4(void)
{
printf("\"That is classified information, Troubleshooter, thank you for your inquiry.\n");
printf(" Please report to an Internal Security self incrimination station as soon as\n");
@ -182,7 +181,7 @@ page4()
return 9;
}
page5()
int page5(void)
{
printf("The computer says, \"Troubleshooter, you are not wearing the correct colour\n");
printf("uniform. You must put on an Ultraviolet uniform immediately. I have seen to\n");
@ -193,7 +192,7 @@ page5()
return choose(6, "You open the package and put on the uniform", 7, "You finally come to your senses and run for it");
}
page6()
int page6(void)
{
printf("The uniform definitely makes you look snappy and pert. It really looks\n");
printf("impressive, and even has the new lopsided lapel fashion that you admire so\n");
@ -205,7 +204,7 @@ page6()
return 8;
}
page7()
int page7(void)
{
printf("The corridor lights dim and are replaced by red battle lamps as the Security\n");
printf("Breach alarms howl all around you. You run headlong down the corridor and\n");
@ -232,7 +231,7 @@ page7()
return 8;
}
page8()
int page8(void)
{
printf("\"Now, about your question, citizen. Christmas was an old world marketing ploy\n");
printf("to induce lower clearance citizens to purchase vast quantities of goods, thus\n");
@ -249,7 +248,7 @@ page8()
return 10;
}
page9()
int page9(void)
{
int choice;
printf("As you walk toward the tubecar that will take you to GDH7-beta, you pass one\n");
@ -262,7 +261,7 @@ page9()
return choice;
}
page10()
int page10(void)
{
int choice;
printf("You stroll briskly down the corridor, up a ladder, across an unrailed catwalk,\n");
@ -290,7 +289,7 @@ page10()
}
}
page11()
int page11(void)
{
printf("The printing on the folder says \"Experimental Self Briefing.\"\n");
printf("You open it and begin to read the following:\n");
@ -321,7 +320,7 @@ page11()
return choose(3,"You wish to ask The Computer for more information about Christmas",10,"You have decided to go directly to Goods Distribution Hall 7-beta");
}
page12()
int page12(void)
{
printf("You walk up to the door and push the button labelled \"push to exit.\"\n");
printf("Within seconds a surly looking guard shoves his face into the small plexiglass\n");
@ -333,7 +332,7 @@ page12()
return choose(11,"You sit down at the table and read the Orange packet",57,"You stare around the room some more");
}
page13()
int page13(void)
{
printf("You step into the shiny plasteel tubecar, wondering why the shape has always\n");
printf("reminded you of bullets. The car shoots forward the instant your feet touch\n");
@ -346,7 +345,7 @@ page13()
return 14;
}
page14()
int page14(void)
{
printf("You manage to pull yourself out of the tubecar and look around. Before you is\n");
printf("one of the most confusing things you have ever seen, a hallway that is\n");
@ -360,7 +359,7 @@ page14()
return 22;
}
page15()
int page15(void)
{
printf("You are set upon by a runty robot with a queer looking face and two pointy\n");
printf("rubber ears poking from beneath a tattered cap. \"Hey mister,\" it says,\n");
@ -384,7 +383,7 @@ page15()
}
}
page16()
int page16(void)
{
printf("The doll is a good buy for fifty credits; it will make a fine Christmas present\n");
printf("for one of your friends. After the sale the robot rolls away. You can use\n");
@ -395,7 +394,7 @@ page16()
return 22;
}
page17()
int page17(void)
{
int i, robot_hp=15;
printf("You whip out your laser and shoot the robot, but not before it squeezes the\n");
@ -432,7 +431,7 @@ page17()
return 22;
}
page18()
int page18(void)
{
printf("You walk to the centre of the hall, ogling like an infrared fresh from the\n");
printf("clone vats. Towering before you is the most unearthly thing you have ever\n");
@ -448,7 +447,7 @@ page18()
else return 20;
}
page19()
int page19(void)
{
printf("Quickly you regain your balance, whirl and fire your laser into the Ultraviolet\n");
printf("citizen behind you. For a moment your heart leaps to your throat, then you\n");
@ -461,7 +460,7 @@ page19()
return choose(34,"You search the body, keeping an eye open for Internal Security",22,"You run away like the cowardly dog you are");
}
page20()
int page20(void)
{
printf("Oh no! you can\'t keep your balance. You\'re falling, falling head first into\n");
printf("the Christmas beast\'s gaping maw. It\'s a valiant struggle; you think you are\n");
@ -473,7 +472,7 @@ page20()
return 22;
}
page21()
int page21(void)
{
printf("You have been wasting the leading citizens of Alpha Complex at a prodigious\n");
printf("rate. This has not gone unnoticed by the Internal Security squad at GDH7-beta.\n");
@ -482,7 +481,7 @@ page21()
return new_clone(45);
}
page22()
int page22(void)
{
printf("You are searching Goods Distribution Hall 7-beta.\n");
switch(dice_roll(1,4))
@ -494,7 +493,7 @@ page22()
}
}
page23()
int page23(void)
{
printf("You go to the nearest computer terminal and declare yourself a mutant.\n");
printf("\"A mutant, he\'s a mutant,\" yells a previously unnoticed infrared who had\n");
@ -503,7 +502,7 @@ page23()
return choose(28,"You tell them that it was really only a bad joke",24,"You want to fight it out, one against twelve");
}
page24()
int page24(void)
{
printf("Golly, I never expected someone to pick this. I haven\'t even designed\n");
printf("the 12 citizens who are going to make a sponge out of you. Tell you what,\n");
@ -511,7 +510,7 @@ page24()
return choose(28,"You change your mind and say it was only a bad joke",25,"You REALLY want to shoot it out");
}
page25()
int page25(void)
{
printf("Boy, you really can\'t take a hint!\n");
printf("They\'re closing in. Their trigger fingers are twitching, they\'re about to\n");
@ -519,7 +518,7 @@ page25()
return choose(28,"You tell them it was all just a bad joke",26,"You are going to shoot");
}
page26()
int page26(void)
{
printf("You can read the cold, sober hatred in their eyes (They really didn\'t think\n");
printf("it was funny), as they tighten the circle around you. One of them shoves a\n");
@ -529,19 +528,19 @@ page26()
return new_clone(32);
}
page27()
int page27(void)
{
/* doesn't exist. Can't happen with computer version.
designed to catch dice cheats */
}
page28()
int page28(void)
{
printf("They don\'t think it\'s funny.\n");
return 26;
}
page29()
int page29(void)
{
printf("\"Psst, hey citizen, come here. Pssfft,\" you hear. When you peer around\n");
printf("you can see someone\'s dim outline in the shadows. \"I got some information\n");
@ -559,7 +558,7 @@ page29()
}
}
page30()
int page30(void)
{
printf("You step into the shadows and offer the man a thirty credit bill. \"Just drop\n");
printf("it on the floor,\" he says. \"So you\'re looking for the Master Retailer, pssfft?\n");
@ -586,7 +585,7 @@ page30()
}
}
page31()
int page31(void)
{
printf("Like any good troubleshooter you make the least expensive decision and threaten\n");
printf("him for information. With lightning like reflexes you whip out your laser and\n");
@ -599,7 +598,7 @@ page31()
return choose(30,"You pay the 30 credits",22,"You pssfft go away stupid");
}
page32()
int page32(void)
{
printf("Finally it\'s your big chance to prove that you\'re as good a troubleshooter\n");
printf("as your previous clone. You walk briskly to mission briefing and pick up your\n");
@ -609,7 +608,7 @@ page32()
return 22;
}
page33()
int page33(void)
{
blast_door=1;
printf("You release the megabolts on the blast door, then strain against it with your\n");
@ -622,7 +621,7 @@ page33()
else return 36;
}
page34()
int page34(void)
{
printf("You have found a sealed envelope on the body. You open it and read:\n");
printf("\"WARNING: Ultraviolet Clearance ONLY. DO NOT READ.\n");
@ -650,7 +649,7 @@ page34()
return choose(46,"You rush off to the nearest computer terminal to expose the commies",22,"You wander off to look for more evidence");
}
page35()
int page35(void)
{
printf("\"Oh master,\" you hear through the gun barrel, \"where have you been? It is\n");
printf("time for the great Christmas gifting ceremony. You had better hurry and get\n");
@ -669,7 +668,7 @@ page35()
return new_clone(32);
}
page36()
int page36(void)
{
printf("\"Congratulations, troubleshooter, you have successfully found the lair of the\n");
printf("Master Retailer and completed the Troubleshooter Training Course test mission,\"\n");
@ -692,7 +691,7 @@ page36()
}
}
page37()
int page37(void)
{
printf("\"Come with me please, Troubleshooter,\" says the Green clearance technician\n");
printf("after he has dislodged your head from the cannon. \"You have been participating\n");
@ -708,7 +707,7 @@ page37()
return 38;
}
page38()
int page38(void)
{
printf("\"I am Plato-B-PHI%d, head of mutant propaganda here at the training course.\n",plato_clone);
printf("If you have any questions about mutants please come to me. Today I will be\n");
@ -725,7 +724,7 @@ page38()
return choose(39,"You volunteer for the test",40,"You duck behind a chair and hope the instructor doesn\'t notice you");
}
page39()
int page39(void)
{
printf("You bravely volunteer to test the mutant detection gun. You stand up and walk\n");
printf("down the steps to the podium, passing a very relieved Troubleshooter along the\n");
@ -743,7 +742,7 @@ page39()
return 41;
}
page40()
int page40(void)
{
printf("You breathe a sigh of relief as Plato-B-PHI picks on the other Troubleshooter.\n");
printf("\"You down here in the front,\" says the instructor pointing at the other\n");
@ -775,7 +774,7 @@ page40()
}
}
page41()
int page41(void)
{
printf("You stumble down the hallway of the Troubleshooter Training Course looking for\n");
printf("your next class. Up ahead you see one of the instructors waving to you. When\n");
@ -789,7 +788,7 @@ page41()
return choose(42,"You respond with the proper Illuminati code phrase, \"Ewige Blumenkraft\"",43,"You ignore this secret society contact");
}
page42()
int page42(void)
{
printf("\"Aha, so you are a member of the elitist Illuminati secret society,\" he says\n");
printf("loudly, \"that is most interesting.\" He turns to the large class already\n");
@ -799,7 +798,7 @@ page42()
return choose(51,"You run for it",52,"You wait for the guard");
}
page43()
int page43(void)
{
printf("You sit through a long lecture on how to recognise and infiltrate secret\n");
printf("societies, with an emphasis on mimicking secret handshakes. The basic theory,\n");
@ -815,7 +814,7 @@ page43()
return choose(44,"You go looking for a computer terminal",55,"You go to the graduation ceremony immediately");
}
page44()
int page44(void)
{
printf("You walk down to a semi-secluded part of the training course complex and\n");
printf("activate a computer terminal. \"AT YOUR SERVICE\" reads the computer screen.\n");
@ -833,7 +832,7 @@ page44()
}
}
page45()
int page45(void)
{
printf("\"Hrank Hrank,\" snorts the alarm in your living quarters. Something is up.\n");
printf("You look at the monitor above the bathroom mirror and see the message you have\n");
@ -847,7 +846,7 @@ page45()
return 10;
}
page46()
int page46(void)
{
printf("\"Why do you ask about the communists, Troubleshooter? It is not in the\n");
printf("interest of your continued survival to be asking about such topics,\" says\n");
@ -855,7 +854,7 @@ page46()
return choose(53,"You insist on talking about the communists",54,"You change the subject");
}
page47()
int page47(void)
{
printf("The Computer orders the entire Vulture squadron to terminate the Troubleshooter\n");
printf("Training Course. Unfortunately you too are terminated for possessing\n");
@ -867,7 +866,7 @@ page47()
return 0;
}
page48()
int page48(void)
{
printf("The tubecar shoots forward as you enter, slamming you back into a pile of\n");
printf("garbage. The front end rotates upward and you, the garbage and the garbage\n");
@ -877,14 +876,14 @@ page48()
return new_clone(45);
}
page49()
int page49(void)
{
printf("The instructor drags your inert body into a specimen detainment cage.\n");
printf("\"He\'ll make a good subject for tomorrow\'s mutant dissection class,\" you hear.\n");
return new_clone(32);
}
page50()
int page50(void)
{
printf("You put down the other Troubleshooter, and then wisely decide to drill a few\n");
printf("holes in the instructor as well; the only good witness is a dead witness.\n");
@ -893,27 +892,27 @@ page50()
return 41;
}
page51()
int page51(void)
{
printf("You run for it, but you don\'t run far. Three hundred strange and exotic\n");
printf("weapons turn you into a freeze dried cloud of soot.\n");
return new_clone(32);
}
page52()
int page52(void)
{
printf("You wisely wait until the instructor returns with a Blue Internal Security\n");
printf("guard. The guard leads you to an Internal Security self incrimination station.\n");
return 2;
}
page53()
int page53(void)
{
printf("You tell The Computer about:\n");
return choose(47,"The commies who have infiltrated the Troubleshooter Training Course\n and the impending People\'s Revolution",54,"Something less dangerous");
}
page54()
int page54(void)
{
printf("\"Do not try to change the subject, Troubleshooter,\" says The Computer.\n");
printf("\"It is a serious crime to ask about the communists. You will be terminated\n");
@ -927,7 +926,7 @@ page54()
else return new_clone(32);
}
page55()
int page55(void)
{
printf("You and 300 other excited graduates are marched from the lecture hall and into\n");
printf("a large auditorium for the graduation exercise. The auditorium is\n");
@ -955,7 +954,7 @@ page55()
return 0;
}
page56()
int page56(void)
{
printf("That familiar strange feeling of deja\'vu envelops you again. It is hard to\n");
printf("say, but whatever is on the other side of the door does not seem to be intended\n");
@ -963,15 +962,14 @@ page56()
return choose(33,"You open the door and step through",22,"You go looking for more information");
}
page57()
int page57(void)
{
printf("In the centre of the room is a table and a single chair. There is an Orange\n");
printf("folder on the table top, but you can\'t make out the lettering on it.\n");
return choose(11,"You sit down and read the folder",12,"You leave the room");
}
next_page(this_page)
int this_page;
int next_page(int this_page)
{
printf("\n");
switch (this_page)
@ -1038,10 +1036,11 @@ int this_page;
}
}
main()
int main(int argc, const char* argv[])
{
/* srand(time(0)); */
instructions(); more();
character(); more();
while((page=next_page(page))!=0) more();
return 0;
}

50
first/testsummary.sh Executable file
View file

@ -0,0 +1,50 @@
#!/bin/sh
echo ""
succeeding="$(find "$@" -size 0)"
notsucceeding="$(find "$@" ! -size 0)"
if [ "$notsucceeding" != "" ]; then
skipped="$(grep -l @@SKIPPED $notsucceeding)"
timedout="$(grep -l @@TIMEDOUT $notsucceeding)"
failed="$(grep -l @@FAIL $notsucceeding)"
else
skipped=
timedout=
failed=
fi
for a in $failed $timedout; do
echo "**** $a"
cat $a
echo ""
done
echo "$(echo "$succeeding" | wc -w) tests passed"
echo "$(echo "$notsucceeding" | wc -w) tests failed to pass"
echo "$(echo "$skipped" | wc -w) were skipped (see build log for details)"
echo "$(echo "$timedout" | wc -w) timed out"
echo "$(echo "$failed" | wc -w) failed"
echo ""
if [ "$failed" != "" ]; then
echo "Failing test logs:"
for t in $failed; do
echo $t
done
exit 1
fi
if [ "$failed" != "" -o "$timedout" != "" ]; then
echo "Test status: SAD FACE (tests are failing)"
exit 1
fi
if [ "$succeeding" = "" ]; then
echo "Test status: PUZZLED FACE (all tests were skipped)"
exit 0
fi
if [ "$skipped" != "" ]; then
echo "Test status: MILDLY PLEASED FACE (some tests were skipped, but the rest pass)"
exit 0
fi
echo "Test status: HAPPY FACE (all tests are passing)"
exit 0

View file

@ -65,9 +65,9 @@ struct outname {
#define RELO1 1 /* 1 byte */
#define RELO2 2 /* 2 bytes */
#define RELO4 3 /* 4 bytes */
#define RELOPPC 4 /* PowerPC 26-bit address */
/* relo 5 is unused */
#define RELOVC4 6 /* VideoCore IV address in 32-bit instruction */
#define RELOPPC 4 /* PowerPC 26-bit address */
#define RELOLIS 5 /* PowerPC lis */
#define RELOVC4 6 /* VideoCore IV address in 32-bit instruction */
#define RELPC 0x2000 /* pc relative */
#define RELBR 0x4000 /* High order byte lowest address. */

22
lang/b/LICENSE Normal file
View file

@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2013-2016 aap
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

53
lang/b/README.md Normal file
View file

@ -0,0 +1,53 @@
A B Compiler
============
abc is a compiler for the [B Programming Language](http://en.wikipedia.org/wiki/B_(programming_language)) that targets x86\_32 processors. It is currently tested under Linux but should work (or at least be easily ported) to other UNIX-like systems. The code is based on [an early C compiler (last1120c)](http://www.cs.bell-labs.com/who/dmr/primevalC.html) by Dennis Ritchie.
Documentation
-------------
* [The Programming Language B](http://9p.io/cm/cs/who/dmr/bintro.html)
* [B Reference by Ken Thompson](http://9p.io/cm/cs/who/dmr/kbman.html) describes a presumably earlier variant of B, which is slightly different from the one described above. The compiler cannot understand it, but I plan to implement a compatibility mode (the differences are minor).
Implementation
--------------
Since B was first implemented for machines with word addressing, some hacking was required to make it work on the byte addressed x86. Addresses filled in by the linker are always byte addresses, so pointers to these addresses are collectively stored at the end of the .data section and are then converted to word addresses at runtime, before main() is called.
The generated assembly is *very* inefficient, not even constant expressions are reduced at compile time. Also I/O is currently not buffered.
How to use
----------
The installation requires a little configuration:
'abc' is a frontend for the actual compiler which feels somewhat like gcc (it also handles assembling and linking). Before you can use it, set it's BDIR variable to the directory of the B compiler.
In the Makefile, change the directory of the 'install' rule to wherever you want your 'abc' file to reside.
Then type
make install libs
which compiles the compiler 'b', installs the 'abc' frontend and compiles the B runtime and library (brt.o and lib.o).
To compile and link a B program, simply type
abc -o outfile file1.b [file2.b ...]
If you want to compile and assemble only:
abc -c file1.b [file2.b ...]
or generate only the assembly:
abc -S file1.b [file2.b ...]
Examples of B programs are in the 'examples' directory, they are mostly from Brian Kernighan's tutorial.
Bugs
----
Since command line parameters aren't passed word-aligned, B can't handle them easily. brt.s copies the strings to another location and aligns them, the space is not dynamically allocated however and only 256 bytes are available by default.
The library is incomplete but has some of the most important functions.
I have only tested the compiler on an x86\_64 gentoo system.

176
lang/b/compiler/b.h Normal file
View file

@ -0,0 +1,176 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <em.h>
#include "astring.h"
#define NCPS 8 /* chars per symbol */
#define HSHSIZ 400 /* hash table size */
#define SWSIZ 230 /* switch table size */
#define CMSIZ 40 /* symbol stack size */
#define SSIZE 20 /* operator and precedence stack size */
#define OSSIZ 300*8 /* space for expression tree */
#define EOS 04 /* end of string marker */
/*
* Holds a B symbol.
* class is one of the storage classes below.
* offset is used depending on class.
*/
struct hshtab {
int class;
int offset;
int dim;
struct hshtab *next;
char name[NCPS+1];
};
struct tnode {
int op;
int value;
struct tnode *tr1;
struct tnode *tr2;
};
struct swtab {
int swlab;
int swval;
};
extern int wordsize;
extern const char* modulename;
int paramsize;
struct hshtab hshtab[HSHSIZ];
int hshused;
int eof;
int peekc;
char ctab[128];
struct hshtab *bsym;
struct hshtab *paraml, *parame;
int cval;
int isn;
char symbuf[NCPS+1];
FILE *sbufp;
int stack;
struct tnode **cp;
int *space;
int ospace[OSSIZ];
int retlab;
int nerror;
struct swtab swtab[SWSIZ];
struct swtab *swp;
int deflab;
extern int contlab;
extern int brklab;
extern int opdope[];
extern int line;
extern int peeksym, peeksym2;
void error(char *s, ...);
void printtoken(int tok, FILE *out);
struct tnode * block(int op, int value, struct tnode *tr1, struct tnode *tr2);
void rcexpr(struct tnode *tr);
void cbranch(struct tnode *t, int lab);
void jump(int lab);
void fnlabel(int l);
void tonativeaddr(void);
void fromnativeaddr(void);
char* manglename(char* name, char prefix);
#define EOFC 0
#define SEMI 1
#define LBRACE 2
#define RBRACE 3
#define LBRACK 4
#define RBRACK 5
#define LPARN 6
#define RPARN 7
#define COLON 8
#define COMMA 9
#define HASH 10
#define MCALL 15
#define CALL 16
#define DECBEF 17
#define INCBEF 18
#define DECAFT 19
#define INCAFT 20
#define EXCLA 21
#define NEG 22
#define AMPER 23
#define STAR 24
#define QUEST 25
#define NOT 26
#define PLUS 30
#define MINUS 31
#define MOD 32
#define TIMES 33
#define DIVIDE 34
#define OR 35
#define AND 36
#define LSHIFT 37
#define RSHIFT 38
#define EQUAL 39
#define NEQUAL 40
#define LESSEQ 41
#define LESS 42
#define GREATEQ 43
#define GREAT 44
#define EOR 45
#define ASSIGN 49
#define ASPLUS 50
#define ASMINUS 51
#define ASMOD 52
#define ASTIMES 53
#define ASDIV 54
#define ASOR 55
#define ASAND 56
#define ASLSH 57
#define ASRSH 58
#define ASEQUAL 59
#define ASNEQL 60
#define ASLEQ 61
#define ASLESS 62
#define ASGTQ 63
#define ASGREAT 64
#define ASEOR 65
#define CON 70
#define STRING 71
#define NAME 72
#define KEYW 73
#define SQUOTE 121
#define DQUOTE 122
#define NEWLN 123
#define SPACE 124
#define LETTER 125
#define DIGIT 126
#define UNKN 127
#define SEOF 200
/* storage classes */
#define AUTO 1
#define EXTERN 2
#define INTERN 3
#define ARG 4
#define KEYWF 5
/* keywords */
#define CASE 3
#define IF 4
#define ELSE 5
#define WHILE 6
#define SWITCH 7
#define GOTO 8
#define RETURN 9
#define DEFAULT 10
#define BREAK 11

1383
lang/b/compiler/b0.c Normal file

File diff suppressed because it is too large Load diff

403
lang/b/compiler/b1.c Normal file
View file

@ -0,0 +1,403 @@
#include "b.h"
/*
* Code generation (EM)
*/
static int
shiftsize(void)
{
switch (wordsize) {
case 1: return 0;
case 2: return 1;
case 4: return 2;
case 8: return 3;
default:
error("unsupported word size");
exit(1);
}
}
void
tonativeaddr(void)
{
C_loc(shiftsize());
C_slu(wordsize);
}
void
fromnativeaddr(void)
{
C_loc(shiftsize());
C_sru(wordsize);
}
char*
manglename(char* name, char prefix)
{
static char buffer[NCPS+3];
buffer[0] = prefix;
buffer[1] = '_';
strcpy(buffer+2, name);
return buffer;
}
void
binary(struct tnode *tr)
{
rcexpr(tr->tr1);
rcexpr(tr->tr2);
}
int
pushargs(struct tnode *tr)
{
int stk;
if (tr == NULL)
return 0;
if (tr->op == COMMA) {
rcexpr(tr->tr2);
stk = pushargs(tr->tr1);
return stk+wordsize;
}
rcexpr(tr);
return wordsize;
}
void
lvalexp(struct tnode *tr)
{
struct hshtab *bs;
char memloc[64];
switch (tr->op) {
case DECBEF:
case INCBEF:
case DECAFT:
case INCAFT:
if (tr->tr1->op == STAR) {
rcexpr(tr->tr1->tr1);
tonativeaddr();
if ((tr->op == DECBEF) || (tr->op == INCBEF)) {
C_dup(wordsize); /* ( addr addr -- ) */
C_loi(wordsize); /* ( addr val -- ) */
if (tr->op == DECBEF)
C_dec(); /* ( addr newval -- ) */
else
C_inc(); /* ( addr newval -- ) */
C_exg(wordsize); /* ( newval addr -- ) */
C_dup(wordsize*2); /* ( newval addr newval addr -- ) */
C_sti(wordsize); /* ( newval addr -- ) */
C_asp(wordsize); /* ( newval -- ) */
} else {
C_dup(wordsize); /* ( addr addr -- ) */
C_loi(wordsize); /* ( addr val -- ) */
C_dup(wordsize*2); /* ( addr val addr val -- ) */
if (tr->op == DECAFT)
C_dec(); /* ( addr val addr newval -- ) */
else
C_inc(); /* ( addr val addr newval -- ) */
C_exg(wordsize); /* ( addr val newval addr -- ) */
C_sti(wordsize); /* ( addr val -- ) */
C_exg(wordsize); /* ( val addr -- ) */
C_asp(wordsize); /* ( val -- ) */
}
} else { /* NAME, checked in "build" */
bs = (struct hshtab *) tr->tr1->tr1;
if (bs->class == EXTERN) {
switch (tr->op) {
case INCBEF:
C_ine_dnam(manglename(bs->name, 'b'), 0);
C_loe_dnam(manglename(bs->name, 'b'), 0);
break;
case DECBEF:
C_dee_dnam(manglename(bs->name, 'b'), 0);
C_loe_dnam(manglename(bs->name, 'b'), 0);
break;
case INCAFT:
C_loe_dnam(manglename(bs->name, 'b'), 0);
C_ine_dnam(manglename(bs->name, 'b'), 0);
break;
case DECAFT:
C_loe_dnam(manglename(bs->name, 'b'), 0);
C_dee_dnam(manglename(bs->name, 'b'), 0);
break;
}
} else if (bs->class == AUTO) {
switch (tr->op) {
case INCBEF:
C_inl(bs->offset);
C_lol(bs->offset);
break;
case DECBEF:
C_del(bs->offset);
C_lol(bs->offset);
break;
case INCAFT:
C_lol(bs->offset);
C_inl(bs->offset);
break;
case DECAFT:
C_lol(bs->offset);
C_del(bs->offset);
break;
}
} else
goto classerror;
}
return;
case ASSIGN:
rcexpr(tr->tr2);
C_dup(wordsize);
if (tr->tr1->op == STAR) {
rcexpr(tr->tr1->tr1);
tonativeaddr();
C_sti(wordsize);
} else { /* NAME */
bs = (struct hshtab *) tr->tr1->tr1;
if (bs->class == EXTERN) {
C_ste_dnam(manglename(bs->name, 'b'), 0);
} else if (bs->class == AUTO) {
C_stl(bs->offset);
} else
goto classerror;
}
return;
case ASPLUS:
case ASMINUS:
case ASMOD:
case ASTIMES:
case ASDIV:
case ASOR:
case ASAND:
case ASLSH:
case ASRSH:
case ASEQUAL:
case ASNEQL:
case ASLEQ:
case ASLESS:
case ASGTQ:
case ASGREAT:
case ASEOR:
tr->op -= ASPLUS-PLUS;
rcexpr(block(ASSIGN,0,tr->tr1,tr));
return;
}
classerror:
error("Storage class");
}
void
rcexpr(struct tnode *tr)
{
int o1, o2;
int stk;
struct hshtab *bs;
if (tr == NULL)
return;
if (opdope[tr->op]&02) {
lvalexp(tr);
return;
}
switch (tr->op) {
case CON:
C_loc(tr->value);
return;
case STRING:
C_lae_dlb(tr->value, 0);
fromnativeaddr();
return;
case NAME: /* only rvalue */
bs = (struct hshtab *) tr->tr1;
if (bs->class == EXTERN)
C_loe_dnam(manglename(bs->name, 'b'), 0);
else if (bs->class == AUTO)
C_lol(bs->offset);
else
goto classerror;
return;
case CALL:
stk = pushargs(tr->tr2);
rcexpr(tr->tr1);
tonativeaddr();
C_cai();
if (stk)
C_asp(stk);
C_lfr(wordsize);
return;
case AMPER:
bs = (struct hshtab *) tr->tr1->tr1;
if (bs->class == EXTERN) {
C_lae_dnam(manglename(bs->name, 'b'), 0);
} else if (bs->class == AUTO) {
C_lal(bs->offset);
} else
goto classerror;
fromnativeaddr();
return;
case STAR: /* only rvalue */
rcexpr(tr->tr1);
tonativeaddr();
C_loi(wordsize);
return;
case PLUS:
binary(tr);
C_adi(wordsize);
return;
case MINUS:
binary(tr);
C_sbi(wordsize);
return;
case TIMES:
binary(tr);
C_mli(wordsize);
return;
case DIVIDE:
binary(tr);
C_dvi(wordsize);
return;
case MOD:
binary(tr);
C_rmi(wordsize);
return;
case AND:
binary(tr);
C_and(wordsize);
return;
case OR:
binary(tr);
C_ior(wordsize);
return;
case EOR:
binary(tr);
C_xor(wordsize);
return;
case LSHIFT:
binary(tr);
C_sli(wordsize);
return;
case RSHIFT:
binary(tr);
C_sri(wordsize);
return;
case EQUAL:
case NEQUAL:
case LESS:
case LESSEQ:
case GREAT:
case GREATEQ:
binary(tr);
C_cmi(wordsize);
switch (tr->op) {
case EQUAL:
C_teq();
break;
case NEQUAL:
C_tne();
break;
case LESS:
C_tlt();
break;
case LESSEQ:
C_tle();
break;
case GREAT:
C_tgt();
break;
case GREATEQ:
C_tge();
break;
}
return;
case EXCLA:
rcexpr(tr->tr1);
C_teq();
return;
case NEG:
rcexpr(tr->tr1);
C_ngi(wordsize);
return;
case NOT:
rcexpr(tr->tr1);
C_com(wordsize);
return;
case QUEST:
cbranch(tr->tr1, o1=isn++);
rcexpr(tr->tr2->tr1);
jump(o2 = isn++);
fnlabel(o1);
rcexpr(tr->tr2->tr2);
fnlabel(o2);
return;
default:
error("Can't print tree (op: %d)", tr->op);
}
classerror:
error("Storage class");
}
/* Prints the tree in RPN, for debugging */
/*
void
rcexpr(struct tnode *tr)
{
struct hshtab *bs;
if (tr == NULL)
printf("(NULL) ");
else if (tr->op == CON)
printf("%d ", tr->value);
else if (tr->op == STRING)
printf("s(L%d) ", tr->value);
else if (tr->op == NAME) {
bs = (struct hshtab *)tr->tr1;
if (bs->class == AUTO)
printf("%s(%d) ", bs->name, bs->offset);
else
printf("%s ", bs->name);
} else {
rcexpr(tr->tr1);
if (opdope[tr->op]&01)
rcexpr(tr->tr2);
printtoken(tr->op, stdout);
}
}
*/

28
lang/b/compiler/build.lua Normal file
View file

@ -0,0 +1,28 @@
cprogram {
name = "em_b",
srcs = {
"./*.c",
},
deps = {
"./*.h",
"modules+headers",
"modules/src/alloc+lib",
"modules/src/data+lib",
"modules/src/em_code+lib_k",
"modules/src/em_data+lib",
"modules/src/em_mes+lib",
"modules/src/print+lib",
"modules/src/string+lib",
"modules/src/system+lib",
}
}
installable {
name = "pkg",
map = {
["$(PLATDEP)/em_b"] = "+em_b",
["$(INSDIR)/share/man/man6/em_b.6"] = "./em_b.6"
}
}

53
lang/b/compiler/em_b.6 Normal file
View file

@ -0,0 +1,53 @@
.TH EM_B 6 2017-01-18
.ad
.SH NAME
em_b \- ACK B compiler
.SH SYNOPSIS
.B ~em/lib/ack/em_b
.RI [ options ]
.SH DESCRIPTION
.I em_b
is a port of the ABC B compiler to the ACK.
Interested parties will be
interested in the upstream distribution here:
.nf
.sp
https://github.com/aap/abc
.fi
.PP
However, the version here has been heavily modified \(em bug reports should be
filed with the ACK, not with the upstream compiler.
.PP
Since B was designed for machines with word addressing, some hacking is
required to make it work on modern, byte addressed machines.
The generated
code expects B variables to contain word addresses, and then generates
code to transform these into native addresses before use (which,
unfortunately, impacts performance).
However, the ACK's linker doesn't know
how to emit word addresses into the program's data sections, and so a
separate fixup stage has to happen at runtime, just before \fBmain()\fP,
to convert the byte addresses into word addresses.
.PP
The end result is that using multiple source files with B is somewhat
unwieldy, requiring each module to be explicitly named and then an extra
stage to generate the fixup code.
See the \fBack\fP(1) and \fBabmodules\fP(1) for details.
.SH OPTIONS
.I em_b
accepts the following flags:
.IP \-w\ \fIsize\fP
Sets the word size, used for scaling addresses.
Usually either 2 or 4.
.IP \-B\ \fIname\fP
Sets the name of the module currently being compiled (used to generate the
fixup table symbol name).
Defaults to \fImain\fP if not specified.
.IP \-i\ \fIfilename\fP
The source B file.
.IP \-o\ \fIfilename\fP
The output compact EM bytecode file.
.SH SEE ALSO
\fIack\fR(1), \fIabmodules\fR(1)
.SH REMARKS
It is very unlikely the \fIem_b\fP will ever be useful for anything.

15
lang/b/distr/Makefile Normal file
View file

@ -0,0 +1,15 @@
CFLAGS=-Wall -Wextra
b: b0.o b1.o
cc b0.o b1.o -o b
b0.o: b0.c b.h
b1.o: b1.c b.h
libs:
./abc -c brt.s lib.b
install: b abc
cp abc $(HOME)/bin
%.o: %.s
as --32 $^ -o $@

95
lang/b/distr/abc Executable file
View file

@ -0,0 +1,95 @@
#!/bin/sh
BDIR="$HOME/abc"
objs="$BDIR/brt.o $BDIR/lib.o"
BC="$BDIR/b"
# compile in.b [out.s]
compile() {
if [ "${1##*.}" != "b" ]; then
echo "Error: can only compile b files" >&2
exit 1
fi
cout=$2
[ "$cout" != "" ] || cout=${1%b}s
tmp1=`mktemp`; tmp2=`mktemp`
$BC $1 $tmp2 $tmp1
retval=$?
cat $tmp1 $tmp2 > $cout
rm $tmp1 $tmp2
[ $retval -eq 0 ] || rm $cout && return $retval
echo $cout
return $retval
}
# assemble in.{sb} [out.o]
assemble() {
atmp=""
ain=$1
aout=$2;
if [ "${1##*.}" = "b" ]; then
[ "$aout" != "" ] || aout=${ain%b}o
ain=`mktemp --suffix=.s`
compile $1 $ain >/dev/null || return 1
atmp="foo"
elif [ "${1##*.}" = "s" ]; then
[ "$aout" != "" ] || aout=${ain%s}o
else
echo "Error: can only compile b and s files" >&2
exit 1
fi
as --32 -g $ain -o $aout
[ "$atmp" != "" ] && rm $ain
echo $aout
}
out=""
action="link"
while getopts "o:Sc" o
do case "$o" in
o) out="$OPTARG";;
S) action=compile;;
c) action=assemble;;
esac
done
shift $(($OPTIND - 1))
# ignore -o option if more than one file given and not linking objs
if [ $# -gt 1 ]; then
if [ "$action" != "link" ]; then
out=""
fi
fi
[ $# -ne 1 ] && havelist=yes
tmpobjs=""
for i in $@; do
if [ "$action" != "link" ]; then
[ "$havelist" = "yes" ] && echo $i:
$action $i $out >/dev/null
[ $? -eq 0 ] || break=1
else
if [ "${i##*.}" = "o" ]; then
objs="$objs $i"
else
[ "$havelist" = "yes" ] && echo $i:
ltmp=`mktemp --suffix=.o`
tmpobjs="$tmpobjs $ltmp"
assemble $i $ltmp >/dev/null
[ $? -eq 0 ] || break=1
fi
fi
done
if [ $break ]; then
[ "$tmpobjs" = "" ] || rm $tmpobjs
echo "Error" >&2
exit 1
fi
if [ "$action" = "link" ]; then
if [ "$out" = "" ]; then
out="-o a.out"
else
out="-o $out"
fi
ld -m elf_i386 -T $BDIR/link.ld $out $objs $tmpobjs
rm $tmpobjs
fi

151
lang/b/distr/brt.s Normal file
View file

@ -0,0 +1,151 @@
.globl _argv
.data
.align 4
.comm argstr,256,4
_argv: .long 0
.text
.globl start
start:
# clear bss (could be done better)
# is it actually necessary?
mov $__bss,%eax
1:
movb $0,(%eax)
inc %eax
cmp $__ebss,%eax
jbe 1b
# copy command line args (can't use them directly, not aligned)
mov %esp,%eax
shr $2,%eax
mov %eax,_argv
mov (%esp),%ecx # number of arguments
mov $argstr,%edi
1:
mov (%esp,%ecx,4),%esi
mov %edi,%eax
shr $2,%eax
mov %eax,(%esp,%ecx,4)
call cpystr
loop 1b
call bsymbs
mov _main,%eax
shl $2,%eax
call *%eax
mov %eax,%ebx
mov $1,%eax
int $0x80
# copy string from esi to edi and convert '\0' to B's '*e', align edi
cpystr:
mov (%esi),%al
test %al,%al
jz 1f
mov %al,(%edi)
inc %edi
inc %esi
jmp cpystr
1:
movb $04,(%edi)
inc %edi
add $3,%edi
and $~3,%edi
ret
# shift addresses filled in by the linker 2 bits to the right
# so B only ever sees word addresses
bsymbs:
mov $__bsymb,%eax
1:
cmp $__ebsymb,%eax
jge 1f
mov (%eax),%ebx
mov (%ebx),%ecx
shr $2,%ecx
mov %ecx,(%ebx)
add $4,%eax
jmp 1b
1:
ret
.globl retrn
retrn:
mov %ebp,%esp
pop %ebp
ret
# handle switch table:
# eax has the value, ebx the address of the switch table
.globl bswitch
bswitch:
xor %ecx,%ecx
1:
mov (%ebx,%ecx,8),%edx
mov 4(%ebx,%ecx,8),%edi
test %edi,%edi
jz 1f # default (last in table)
cmp %eax,%edx
je 2f
inc %ecx
jmp 1b
1:
jmp *%edx
2:
jmp *%edi
#
# Library functions in assembly
#
.globl _exit
.data
.align 4
.section .bsymb; .long _exit; .data
_exit: .long 1f
.text
.align 4
1: mov $1,%eax
mov $0,%ebx
int $0x80
.globl _write
.data
.align 4
.section .bsymb; .long _write; .data
_write: .long 1f
.text
.align 4
1: mov 4(%esp),%ebx
mov 8(%esp),%ecx
shl $2,%ecx
mov 12(%esp),%edx
mov $4,%eax
int $0x80
ret
.globl _read
.data
.align 4
.section .bsymb; .long _read; .data
_read: .long 1f
.text
.align 4
1: mov 4(%esp),%ebx
mov 8(%esp),%ecx
shl $2,%ecx
mov 12(%esp),%edx
mov $3,%eax
int $0x80
ret
.globl _inv
.data
.align 4
.section .bsymb; .long _inv; .data
_inv: .long 1f
.text
.align 4
1: mov 4(%esp),%eax
not %eax
ret

View file

@ -0,0 +1,7 @@
main() {
auto a, b, c, sum;
a = 1; b = 2; c = 3;
sum = a+b+c;
putnumb(sum);
}

View file

@ -0,0 +1,9 @@
main() {
extrn a, b, c;
putchar(a); putchar(b); putchar(c); putchar('!*n');
}
a 'hell';
b 'o, w';
c 'orld';

View file

@ -0,0 +1,13 @@
main() {
extrn a, b, c, d;
put2char(a,b);
put2char(c,d);
}
put2char(x,y) {
putchar(x);
putchar(y);
}
a 'hell'; b 'o, w'; c 'orld'; d '!*n';

View file

@ -0,0 +1,7 @@
main() {
auto c;
read:
c= getchar();
putchar(c);
if(c != '*n') goto read;
}

View file

@ -0,0 +1,10 @@
main() {
auto c;
while (1) {
while ( (c=getchar()) != ' ')
if (putchar(c) == '*n') exit();
putchar( '*n' );
while ( (c=getchar()) == ' '); /* skip blanks */
if (putchar(c)=='*n') exit();
}
}

View file

@ -0,0 +1,10 @@
main() {
extrn argv;
auto i;
i = 1;
printf("%d args:*n", argv[0]);
while (i <= argv[0])
printf("%s*n", argv[i++]);
return(0);
}

111
lang/b/distr/lib.b Normal file
View file

@ -0,0 +1,111 @@
char(s, n)
return((s[n/4]>>8*(n%4))&0377); /* s[n/4] */
lchar(s, n, char) {
auto i;
i = 8*(n%4);
char = (char&0377)<<i;
i = inv(0377<<i);
s[(n/4)*4] = s[n/4]&i | char;
}
putchar(char) {
auto c, i;
c = char;
i = 4;
while ((c&0377) != '*e' & (c&0377) != '*0' & i != 0) {
i--;
c =>> 8;
}
write(1, &char, 4-i);
return(char);
}
getchar() {
auto char;
char = 0;
read(1, &char, 1);
return(char);
}
printn(n,b) {
extrn putchar;
auto a;
if (a = n/b)
printn(a, b);
putchar(char("0123456789ABCDEF", n%b));
}
putnumb(n) {
printn(n,10);
putchar('*n');
}
putstr(s) {
auto c, i;
i = 0;
while ((c = char(s,i++)) != '*e')
putchar(c);
}
getstr(s) {
auto c, i;
while ((c = getchar()) != '*n')
lchar(s,i++,c);
lchar(s,i,'*e');
return(s);
}
printf(fmt, x1,x2,x3,x4,x5,x6,x7,x8,x9) {
extrn printn, char, putchar;
auto adx, x, c, i, j;
i = 0;
adx = &x1;
loop:
while((c=char(fmt,i++)) != '%') {
if(c == '*e')
return;
putchar(c);
}
x = *adx++;
switch (c = char(fmt,i++)) {
case 'd':
case 'o':
if(x < 0) {
x = -x;
putchar('-');
}
printn(x, c=='o'?8:10);
goto loop;
case 'x':
if(x < 0) {
x = -x;
putchar('-');
}
printn(x, 16);
goto loop;
case 'c':
putchar(x);
goto loop;
case 's':
j = 0;
while((c=char(x,j++)) != '*e')
putchar(c);
goto loop;
}
putchar('%');
i--;
adx--;
goto loop;
}

21
lang/b/distr/link.ld Normal file
View file

@ -0,0 +1,21 @@
OUTPUT_FORMAT("elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(start)
SECTIONS
{
. = 0x400000;
.text : { *(.text) }
. = 0x8000000;
.data : {
*(.data)
__bsymb = .;
*(.bsymb)
__ebsymb = .;
}
. = ALIGN(16);
__bss = .;
.bss : { *(.bss) }
__ebss = .;
}

28
lang/b/lib/b.h Normal file
View file

@ -0,0 +1,28 @@
#ifndef B_H
#define B_H
#include <stdlib.h>
#include <stdio.h>
#if EM_PSIZE == 2
#define SHIFT 1
#elif EM_PSIZE == 4
#define SHIFT 2
#elif EM_PSIZE == 8
#define SHIFT 3
#else
#error Unsupported EM_PSIZE
#endif
extern FILE* input_unit;
extern FILE* output_unit;
#define END 4
extern uintptr_t* bmodule_main[];
extern void patch_addresses(uintptr_t** p);
extern void binit(void);
#endif

27
lang/b/lib/build.lua Normal file
View file

@ -0,0 +1,27 @@
include("plat/build.lua")
for _, plat in ipairs(vars.plats) do
acklibrary {
name = "lib_"..plat,
srcs = {
"./*.c",
"./*.e",
},
hdrs = {}, -- must be empty
deps = {
"./*.h",
"h+emheaders",
"lang/cem/libcc.ansi/headers+pkg",
"plat/"..plat.."/include+pkg",
},
vars = { plat = plat }
}
installable {
name = "pkg_"..plat,
map = {
["$(PLATIND)/"..plat.."/libb.a"] = "+lib_"..plat,
}
}
end

10
lang/b/lib/init.c Normal file
View file

@ -0,0 +1,10 @@
#include "b.h"
#include <stdarg.h>
#include <string.h>
#include <limits.h>
void binit(void)
{
patch_addresses(bmodule_main);
}

186
lang/b/lib/main.c Normal file
View file

@ -0,0 +1,186 @@
#include "b.h"
#include <stdarg.h>
#include <string.h>
#include <limits.h>
extern intptr_t i_main(intptr_t argc, const char* argv[]);
FILE* input_unit;
FILE* output_unit;
static intptr_t i_char(intptr_t s, intptr_t n)
{
const char* p = (const char*)(s<<SHIFT);
return p[n];
}
static void i_lchar(intptr_t s, intptr_t n, intptr_t c)
{
char* p = (char*)(s<<SHIFT);
p[n] = c;
}
static intptr_t i_getchar(void)
{
return fgetc(input_unit);
}
static intptr_t i_putchar(intptr_t c)
{
fputc(c, output_unit);
return c;
}
static intptr_t i_putstr(intptr_t s)
{
char* p = (char*)(s<<SHIFT);
char c;
while ((c = *p++) != END)
fputc(c, output_unit);
return s;
}
static intptr_t i_getstr(intptr_t s)
{
char* p = (char*)(s<<SHIFT);
for (;;)
{
int c = fgetc(input_unit);
if ((c == -1) || (c == '\n'))
break;
*p++ = c;
}
*p++ = END;
return s;
}
static void i_flush(void)
{
fflush(output_unit);
}
static int tochar(int n)
{
if (n <= 9)
return n + '0';
return n - 10 + 'a';
}
static void putnum(intptr_t value, int base)
{
int i;
char s[32];
if (value < 0)
{
fputc('-', output_unit);
value = -value;
}
i = 0;
do
s[i++] = tochar(value % base);
while ((value /= base) > 0);
do
fputc(s[--i], output_unit);
while (i > 0);
}
static void i_printf(intptr_t s, ...)
{
char* p = (char*)(s<<SHIFT);
char c;
va_list ap;
va_start(ap, s);
while ((c = *p++) != END)
{
switch (c)
{
case '%':
{
intptr_t ss = va_arg(ap, intptr_t);
switch ((c = *p++))
{
case 's':
i_putstr(ss);
break;
case 'd':
putnum(ss, 10);
break;
case 'o':
putnum(ss, 8);
break;
case 'x':
putnum(ss, 16);
break;
case 'c':
fputc(ss, output_unit);
break;
default:
fputc('?', output_unit);
break;
}
break;
}
default:
fputc(c, output_unit);
break;
}
}
va_end(ap);
}
uintptr_t b_char = (uintptr_t)i_char;
uintptr_t b_lchar = (uintptr_t)i_lchar;
uintptr_t b_getchar = (uintptr_t)i_getchar;
uintptr_t b_putchar = (uintptr_t)i_putchar;
uintptr_t b_putstr = (uintptr_t)i_putstr;
uintptr_t b_getstr = (uintptr_t)i_getstr;
uintptr_t b_flush = (uintptr_t)i_flush;
uintptr_t b_printf = (uintptr_t)i_printf;
static uintptr_t* bmodule_stdlib[] =
{
&b_char,
&b_lchar,
&b_getchar,
&b_putchar,
&b_putstr,
&b_getstr,
&b_flush,
&b_printf,
0
};
void patch_addresses(uintptr_t** p)
{
while (*p)
{
uintptr_t* q = *p++;
*q >>= SHIFT;
}
}
int main(int argc, const char* argv[])
{
patch_addresses(bmodule_stdlib);
binit();
input_unit = stdin;
output_unit = stdout;
return i_main(argc, NULL);
}

View file

@ -10,8 +10,8 @@ for _, plat in ipairs(vars.plats) do
hdrs = {}, -- must be empty
deps = {
"h+emheaders",
"lang/cem/libcc.ansi/headers+headers",
"plat/"..plat.."/include+headers",
"lang/cem/libcc.ansi/headers+pkg",
"plat/"..plat.."/include+pkg",
},
vars = { plat = plat }
}

View file

@ -522,7 +522,7 @@ scanstring()
yylval.integer= genemlabel();
C_rom_dlb((label)i,(arith)0);
C_rom_icon("9999",(arith)BEMINTSIZE);
C_rom_icon(itoa(length),(arith)BEMINTSIZE);
C_rom_icon(myitoa(length),(arith)BEMINTSIZE);
}
#ifdef YYDEBUG
if (yydebug) print("STRVALUE found\n");

View file

@ -72,5 +72,5 @@ extern int dataused;
extern Linerecord *currline;
extern char *itoa();
extern char *myitoa();
extern char *salloc();

View file

@ -670,7 +670,7 @@ gendata()
C_df_dnam("datfdes");
C_rom_dnam("datfname",(arith)0);
C_rom_cst((arith)1);
C_rom_cst((arith)(itoa(strlen(datfname))));
C_rom_cst((arith)(myitoa(strlen(datfname))));
C_df_dnam("dattdes");
C_rom_dnam("dattyp",(arith)0);
C_rom_cst((arith)1);

View file

@ -69,7 +69,7 @@ illegalcmd()
char *itoa(i)
char *myitoa(i)
int i;
{
static char buf[30];

View file

@ -51,8 +51,8 @@ for _, plat in ipairs(vars.plats) do
},
hdrs = {}, -- must be empty
deps = {
"lang/cem/libcc.ansi/headers+headers",
"plat/"..plat.."/include+headers",
"lang/cem/libcc.ansi/headers+pkg",
"plat/"..plat.."/include+pkg",
"./malloc/malloc.h",
"./math/localmath.h",
"./stdio/loc_incl.h",

View file

@ -113,6 +113,7 @@ cprogram {
"h+emheaders",
"modules+headers",
"modules/src/alloc+lib",
"modules/src/data+lib",
"modules/src/em_code+lib_k",
"modules/src/em_data+lib",
"modules/src/em_mes+lib",

View file

@ -9,48 +9,50 @@
/* $Id$ */
#include "debug.h"
#include "parameters.h"
#include "debug.h"
#include <alloc.h>
#include <assert.h>
#include <em_arith.h>
#include <em_label.h>
#include <stdlib.h>
#include <assert.h>
#include <em_arith.h>
#include <em_label.h>
#include <alloc.h>
#include <astring.h>
#include "idf.h"
#include "input.h"
#include "scope.h"
#include "LLlex.h"
#include "def.h"
#include "Lpars.h"
#include "f_info.h"
#include "main.h"
#include "node.h"
#include "type.h"
#include "misc.h"
#include "LLlex.h"
#include "Lpars.h"
#include "def.h"
#include "f_info.h"
#include "idf.h"
#include "input.h"
#include "main.h"
#include "misc.h"
#include "node.h"
#include "scope.h"
#include "type.h"
#ifdef DEBUG
long sys_filesize();
long sys_filesize();
#endif
t_idf *DefId;
t_idf* DefId;
char *
getwdir(fn)
register char *fn;
char*
getwdir(fn) register char* fn;
{
register char *p;
char *strrchr();
register char* p;
char* strrchr();
while ((p = strrchr(fn,'/')) && *(p + 1) == '\0') {
while ((p = strrchr(fn, '/')) && *(p + 1) == '\0')
{
/* remove trailing /'s */
*p = '\0';
}
if (p) {
if (p)
{
*p = '\0';
fn = Salloc(fn, (unsigned) (p - &fn[0] + 1));
fn = Salloc(fn, (unsigned)(p - &fn[0] + 1));
*p = '/';
return fn;
}
@ -58,20 +60,15 @@ getwdir(fn)
}
STATIC
GetFile(name)
char *name;
GetFile(name) char* name;
{
/* Try to find a file with basename "name" and extension ".def",
in the directories mentioned in "DEFPATH".
*/
char buf[15];
char *strncpy(), *strcat();
strncpy(buf, name, 10);
buf[10] = '\0'; /* maximum length */
strcat(buf, ".def");
char* buf = aprintf("%s.def", name);
DEFPATH[0] = WorkingDir;
if (! InsertFile(buf, DEFPATH, &(FileName))) {
if (!InsertFile(buf, DEFPATH, &(FileName)))
{
error("could not find a DEFINITION MODULE for \"%s\"", name);
return 0;
}
@ -81,25 +78,25 @@ GetFile(name)
return 1;
}
t_def *
GetDefinitionModule(id, incr)
register t_idf *id;
t_def*
GetDefinitionModule(id, incr) register t_idf* id;
{
/* Return a pointer to the "def" structure of the definition
module indicated by "id".
We may have to read the definition module itself.
Also increment level by "incr".
*/
register t_def *df;
register t_def* df;
static int level;
t_scopelist *vis;
char *fn = FileName;
t_scopelist* vis;
char* fn = FileName;
int ln = LineNumber;
t_scope *newsc;
t_scope* newsc;
level += incr;
df = lookup(id, GlobalScope, D_IMPORTED, 0);
if (!df) {
if (!df)
{
/* Read definition module. Make an exception for SYSTEM.
*/
extern int ForeignFlag;
@ -110,53 +107,62 @@ GetDefinitionModule(id, incr)
newsc = CurrentScope;
vis = CurrVis;
newsc->sc_defmodule = incr;
if (!strcmp(id->id_text, "SYSTEM")) {
if (!strcmp(id->id_text, "SYSTEM"))
{
do_SYSTEM();
df = lookup(id, GlobalScope, D_IMPORTED, 0);
}
else {
if (!is_anon_idf(id) && GetFile(id->id_text)) {
else
{
if (!is_anon_idf(id) && GetFile(id->id_text))
{
char *f = FileName;
char* f = FileName;
DefModule();
df = lookup(id, GlobalScope, D_IMPORTED, 0);
if (level == 1 &&
(df && !(df->df_flags & D_FOREIGN))) {
if (level == 1 && (df && !(df->df_flags & D_FOREIGN)))
{
/* The module is directly imported by
the currently defined module, and
is not foreign, so we have to
remember its name because we have
to call its initialization routine
*/
static t_node *nd_end;
register t_node *n;
extern t_node *Modules;
static t_node* nd_end;
register t_node* n;
extern t_node* Modules;
n = dot2leaf(Def);
n->nd_def = newsc->sc_definedby;
if (nd_end) nd_end->nd_NEXT = n;
else Modules = n;
if (nd_end)
nd_end->nd_NEXT = n;
else
Modules = n;
nd_end = n;
}
free(f);
}
else {
else
{
df = lookup(id, GlobalScope, D_IMPORTED, 0);
newsc->sc_name = id->id_text;
}
}
close_scope(SC_CHKFORW);
if (! df) {
if (!df)
{
df = MkDef(id, GlobalScope, D_ERROR);
df->mod_vis = vis;
newsc->sc_definedby = df;
}
}
else if (df->df_flags & D_BUSY) {
else if (df->df_flags & D_BUSY)
{
error("definition module \"%s\" depends on itself",
id->id_text);
id->id_text);
}
else if (df == Defined && level == 1) {
else if (df == Defined && level == 1)
{
error("cannot import from current module \"%s\"", id->id_text);
df->df_kind = D_ERROR;
}

View file

@ -1,10 +1,10 @@
.TH EM_M2 6 "$Revision$"
.TH EM_M2 6 2017-01-18
.ad
.SH NAME
em_m2 \- ACK Modula\-2 compiler
.SH SYNOPSIS
.B ~em/lib.bin/em_m2
.RI [ option ]
.RI [ option ]
.I source
.I destination
.SH DESCRIPTION
@ -15,9 +15,9 @@ into EM code.
The input is taken from
.IR source ,
while the
EM code is written on
EM code is written on
.IR destination .
.br
.PP
.I Option
is a, possibly empty, sequence of the following combinations:
.IP \fB\-I\fIdirname\fR
@ -65,7 +65,8 @@ make all procedure names global, so that \fIadb\fR(1) understands them.
.IP \fB\-g\fR
produce a DBX-style symbol table.
.IP \fB\-l\fR
enable local extensions. Currently, there are two local extensions:
enable local extensions.
Currently, there are two local extensions:
procedure constants, and the type LONGCARD.
.IP \fB\-s\fR
make INTEGER ranges symmetric, t.i., MIN(INTEGER) = - MAX(INTEGER).
@ -77,11 +78,11 @@ disable all range checks.
enable extra array bound checks, for machines that do not implement the
EM ones.
.IP \fB-U\fR
allow for underscores within identifiers. Identifiers may not start with
allow for underscores within identifiers.
Identifiers may not start with
an underscore, even if this flag is given.
.IP \fB-3\fR
only accept Modula-2 programs that strictly conform to [1].
.LP
.SH SEE ALSO
\fIack\fR(1), \fImodula-2\fR(1)
.IP [1]

View file

@ -19,11 +19,6 @@ Implementation modules and program modules must reside in files having a
.PP
The name of the file in which a definition module is stored must be the same as
the module-name, apart from the extension.
Also, in most Unix systems filenames are only 14 characters long.
So, given an IMPORT declaration for a module called "LongModulName",
the compiler will try to open a file called "LongModulN.def".
The requirement does not hold for implementation or program modules,
but is certainly recommended.
.SH CALLING THE COMPILER
The easiest way to do this is to let the \fIack\fR(1) program do it.
So, to compile a program module "prog.mod", just call

File diff suppressed because it is too large Load diff

View file

@ -29,8 +29,8 @@ for _, plat in ipairs(vars.plats) do
},
hdrs = {}, -- must be empty
deps = {
"lang/cem/libcc.ansi/headers+headers",
"plat/"..plat.."/include+headers",
"lang/cem/libcc.ansi/headers+pkg",
"plat/"..plat.."/include+pkg",
"h+emheaders",
},
vars = { plat = plat }

View file

@ -355,7 +355,7 @@ void zgt(lab) int lab; { C_zgt((label) lab); }
void zlt(lab) int lab; { C_zlt((label) lab); }
void zne(lab) int lab; { C_zne((label) lab); }
char *itoa(i) long i;
char *myitoa(i) long i;
{
static char a[sizeof(long)*3];
sprint(a, "%ld", i);
@ -364,7 +364,7 @@ char *itoa(i) long i;
void rom(size, c) int size; long c;
{
C_rom_icon(itoa(c), (arith) size);
C_rom_icon(myitoa(c), (arith) size);
}
void lin()

View file

@ -164,14 +164,10 @@ register int delim;
Malloc((unsigned) sizeof(struct string));
register char *p;
register int len = ISTRSIZE;
str->s_str = p = Malloc((unsigned int) ISTRSIZE);
for( ; ; ) {
LoadChar(ch);
if( ch & 0200 ) {
fatal("non-ascii '\\%03o' read", ch & 0377);
/*NOTREACHED*/
}
if( class(ch) == STNL ) {
lexerror("newline in string");
LineNumber++;
@ -310,11 +306,6 @@ again:
LoadChar(ch);
if( !options['C'] ) /* -C : cases are different */
TO_LOWER(ch);
if( (ch & 0200) && ch != EOI ) {
fatal("non-ascii '\\%03o' read", ch & 0377);
/*NOTREACHED*/
}
}
switch( class(ch) ) {
@ -420,7 +411,7 @@ again:
/* dtrg: removed to allow Pascal programs to access system routines
* (necessary to make them do anything useful). What's this for,
* anyway? */
#if 0
if( buf[0] == '_' ) lexerror("underscore starts identifier");
#endif
@ -492,7 +483,7 @@ again:
PushBack();
goto end;
}
}
if( ch == 'e' || ch == 'E' ) {
char *tp = np; /* save position in string */

Some files were not shown because too many files have changed in this diff Show more