GithubHelp home page GithubHelp logo

davidkinder / inform6 Goto Github PK

View Code? Open in Web Editor NEW
198.0 198.0 32.0 2.6 MB

The latest version of the Inform 6 compiler, used for generating interactive fiction games.

Home Page: http://inform-fiction.org/

License: Other

HTML 1.44% C 98.56%

inform6's People

Contributors

cspiegel avatar davidgriffith avatar davidkinder avatar emacsuser avatar erkyrath avatar hlabrand avatar kroc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

inform6's Issues

Clarify inform6 -h2 output regarding v7

This is part of the output for inform6 -h2:

v3 compile to version-3 ("Standard") story file
v4 compile to version-4 ("Plus") story file
v5 compile to version-5 ("Advanced") story file: the default
v6 compile to version-6 (graphical) story file
v8 compile to version-8 (expanded "Advanced") story file
...
B use big memory model (for large V6/V7 files)

So in essence there's no documented way to tell the compiler to build a v7 file, but if you do, -B might be useful.

there's no makefile

This isn't a major issue, but the repo doesn't have a makefile. I've hacked one up and placed it here.

I think inform6 needs a Makefile, so I wrote one.

There are two reasons I think it should:

  • Proper choice of compilation technique can have a significant effect on the speed of inform6 (this makes an inform6 nearly twice as fast as the one in Debian/Ubuntu)
  • Being able to type "make" rather than invoking gcc directly is a lower-barrier-of-entry process for typical Linux users

This should of course be named Makefile when checked into the repo, but github wouldn't let me upload it under that name.

Makefile.txt

Fix compiler warnings

I think it would be nice for Inform6 to compile without warnings when -Wall -Wextra are used. To this end I would like to take on the task of fixing these warnings.

Forward-declared properties do not work right

This is a problem in both Z-code and Glulx, but the problems are different.

In Z-code, if you have a line like

o.prop = val;

where prop is an individual property not yet defined, the compiler erroneously generates a set_prop opcode (which only works for common properties).

In Glulx, if you refer to o.prop where prop is a common property not yet defined, you get an error:

"<constructing output>", line 0: Error:  *** Illegal backpatch marker in forward-declared symbol

Both of these cases are supposed to work. The Glulx case is an oversight on my part. The Z-code case appears to be a typo in the check_property_operator() function.

Object -> ignores object which has a name reference to parent

Consider this code:

Object Kitchen "Kitchen"
  with description "Nice kitchen",
  has light;
  
Object bag "bag" selfobj
  has container open;

Object -> hammer "hammer";

This places the hammer in the kitchen. I think this is weird and inconvenient behaviour, but maybe it's intentional. And I realize that changing it could break existing code.

Fatal error with KeyDelay() and the recording function when recording is replayed

As I've explored this issue at https://gitlab.com/DavidGriffith/frotz/issues/136, it occurred to me that the problem may lie in any of three places: the Inform 6 Compiler, the Inform 6 Library, or the Frotz core.

If you wait for the KeyDelay() delay by not pressing a key, you get a fatal error when you replay the recording during the game, otherwise you get: "I beg your pardon?"
Transcript:

Release 1 / Serial number 190801 / Inform v6.34 Library v6.12.3pre S

Room 1
You are in room 1.
Come in, Room 2 is waiting for you.

>recording
Enter a file name.
Default is "test.rec": 
[Command recording on.]

>enter
You are hesitating... then you decide to enter.

Room 2
You are in room 2.

>recording off
[Command recording off.]

>replay
Enter a file name.
Default is "test.rec": 
Do you want MORE prompts? (y/n) >y
[Replaying commands.]

>enter
You can't go that way.

>Fatal error: Illegal opcode
[Hit any key to exit.]

Source code:

Include "parser";
Include "verblib";

Object room1 "Room 1"
with description "You are in room 1. ^Come in, Room 2 is waiting for you.",
	Before [;
		GoIn:
			print "You are hesitating... ";
			KeyDelay(15);
			print "then you decide to enter.^";
			PlayerTo(room2);
			rtrue;
	], 
has light;

Object room2 "Room 2"
with description "You are in room 2." 
has light;

[ Initialise; location = room1; ];

Include "grammar";

Add support for extending and not replacing the include_dir

Hi there,

First of all please tell me if it would have been better to file a report on I7's Mantis instead of here; I chose here as I find GitHub more convenient and it's very-specific to the compiler.

I just packaged the I6 compiler for the Mageia Linux distro based on Ben Finney's Debian packaging. We both compile I6 with -DInclude_Directory="\"/usr/share/inform6/library\"", which works great.

So I6 will look by default in this system-wide path for the libraries. Now, when I want to build a project that uses a custom library, I would like to have the possibility to define an additional path for library lookup using a command line switch. There is already +include_path=<path> (and +<path>), but it overrides the system-defined one.

See e.g.:

$ ls
katabasis.inf
scenic5sens.h

$ inform -v8 +Language_name=French katabasis.inf katabasis.z8
Inform 6.33 for Linux (10th May 2014)
[Compil� avec la version 2.3 de la biblioth�que francophone.]
line 795: Fatal error: Couldn't open source file "/usr/share/inform6/library/scenic5sens.h"

$ inform -v8 +Language_name=French +include_path=./ katabasis.inf katabasis.z8
Inform 6.33 for Linux (10th May 2014)
line 11: Fatal error: Couldn't open source file "./Parser.h"

The only solution is to specify both the system path and the custom path in the switch, which is tiresome:

$ inform -v8 +Language_name=French +include_path=/usr/share/inform6/library/,./ katabasis.inf katabasis.z8
Inform 6.33 for Linux (10th May 2014)
[Compil� avec la version 2.3 de la biblioth�que francophone.]
Compiling Scenic.h

To fix this, there could either be a new switch (e.g. +include_path_add=) that only extends the path instead of replacing it (if the possibility to fully override the system-defined path should be kept). Another possibility would be to support an assignment like += instead of =, e.g. +include_path+=./.

Recursive abbreviations

The following code is legal:

Abbreviate "@00 Smith";

[ Initialise ;
    string 0 "John";
];

(The command "string n "str"" is named "printing variable" on page 30 of the DM4; it is implemented as an abbreviation. The Z-Machine has 96 abbreviations : 64 can be defined by Abbreviate, 32 with printing variables.)

As mentioned here, this however violates paragraph 3.3.1 of the Z-machine Standards Document 1.1, "Abbreviation string-printing follows all the rules of this section except that an abbreviation string must not itself use abbreviations".
Virtually no interpreter (Infocom's, 8-bit ones, Frotz, etc.) ever complain about this, except Bocfel (so, Spatterlight on OS X and Gargoyle on Linux), which crashes.

The compiler should give a warning, or an error, for this case.
Similarly, @00 should not be included in "string 1", etc. (But I don't know if this is even allowed by the compiler; if it is, it could definitely create infinite loops, or at least nasty recursive patterns.)

Ifdef doesn't work at the start of a switch block

This gives an error:

`
Constant PRINT_WARNING;

[Initialise x;
x = 1;
switch(x) {
#IfDef PRINT_WARNING;
1: print "1!^";
#Endif;
default: print "Other^";
}
print "End.^";
];
`

But if you add 0: print "0!^"; just before #ifdef, it works.

Wanted: Warnings for using objects and attributes incorrectly

Inform 6 has some operators where the operator on the left hand side must be a valid object ID and/or the one on the right hand side must be an object ID, a property ID or an attribute ID. In a few cases, giving the wrong kind of entity raises a warning. I can see that these operators confuse a lot of newcomers to Inform 6, and even I made a stupid mistake in this area recently ( if(player has necklace) ... :) ). Wouldn't it be nice with warnings when using the wrong kind of entity for these operators? Like for Lamp.light = true or if(Lamp provides light) etc. Here's a program covering some of the cases, with comments for the ones that currently give a warning.

Property p1;
Property p2;
Property p3;
Property p4;
Property p5;
Property p6;

Attribute a1;
Attribute a2;
Attribute a3;
Attribute a4;
Attribute a5;
Attribute a6;

Object o1 "o1"
	with
		p1 1,
		p2 1,
		p3 1,
		p4 1,
		p5 1,
		p6 1,
	has a1 a2 a3 a4 a5 a6;

Object o2 "o2";

[main;
	if(o2 has o1) print "o2 has o1";
	if(o2 has p1) print "o2 has p1"; ! Warning: Property not qualified by object
	if(o2 provides o1) print "o2 provides o1";
	if(o2 provides a1) print "o2 provides a1";
	if(o2 in p1) print "o2 in p1"; ! Warning: Property not qualified by object
	if(o2 in a1) print "o2 in a1";

	if(p1 has a1) print "p1 has a1"; ! Warning: Property not qualified by object
	if(p1 provides p1) print "p1 provides p1"; ! Warning: Property not qualified by object
	if(p1 in o1) print "p1 in o1"; ! Warning: Property not qualified by object

	if(a1 has a1) print "a1 has a1";
	if(a1 provides p1) print "a1 provides p1";
	if(a1 in o1) print "a1 in o1";

	if(o1.o2) print "o1.o2 ~= 0";
	if(o1.a2) print "o1.a2 ~= 0";

	give o1 p1; ! Warning: This is not a declared Attribute: "p1", Bare property name found. "self.prop" intended?
	give o1 o2; ! Warning: This is not a declared Attribute: "o2"

	give a1 a2;
	give p1 a2; ! Warning: Bare property name found. "self.prop" intended?
];

Add option to search alternate ".infh" extension for Includes

That Inform uses the same ".h" extension as C for its library and extension files sometimes causes issues when editing such files, because editors and source navigation tools assume that those Inform files are C headers.

Certain editors (ex. jEdit) can perform more sophisticated file type analysis, but others (ex. Notepad++) base the file type purely on the extension, and thus will always open .h files as C code.

Particularly when trying to load both the Inform compiler and standard library into an IDE project (in my case, Source Insight), that their extensions overlap causes problems with symbol referencing, etc.

This patch adds an '-I' switch that causes the compiler to search for a ".infh" file--falling back to ".h" if not present--when Include'ing a file from Inform source. In this way, an author can choose to rename the standard library files and any extensions to ".infh" to get customized syntax highlighting, etc.

jessepav@972b606

Command-line option to set a (numeric) constant

Proposed here: https://intfiction.org/t/define-a-constant-on-commandline-for-inform-6-compiler/50285

I'm thinking the option would look like

$#IDENTIFIER
$#IDENTIFIER=NUM

--define IDENTIFIER
--define IDENTIFIER=NUM

If no value is specified, default to 0 (consistent with the Constant directive).

We'd have to validate that the identifier is all ascii (Inform doesn't permit non-ascii characters outside of quotes, regardless of the -C setting). And doesn't start with a digit. Also the identifier shouldn't clash with any of the compiler-defined symbols like WORDSIZE or sw__var.

Broken Iftrue?

This doesn't compile:

Constant FOO "String";

Default FOO 5;

[ Test;
#IfTrue FOO < 10;
	print "Hello^";
#EndIf;
	print "Goodbye^";
];

[main b;
	Test();
	@read_char b;
];

Is it that the value of FOO isn't known on the first pass, since the compiler can't know the final address of the string until it has compiled the code?

This is a pattern we use in PunyInform for replacing library messages, and no one has complained that it doesn't work yet, but maybe they haven't tried it just this way.

Warning for characters in name property does not happen in Glulx

In Z-code, if you write:

Object foo with name 'x';

...you get a warning:

line 5: Warning:  'name' property should only contain dictionary words

('x' being a character literal, not a dict word.) (If you want a short dict word it would be 'x//'.)

This warning doesn't happen in Glulx.

The difference is just these lines:

! objects.c:1163, zcode
            if ((!individual_property) && (property_number==1)
                && ((token_type != SQ_TT) || (strlen(token_text) <2 )) 
                && (token_type != DQ_TT)
                )
                warning ("'name' property should only contain dictionary words");

! objects.c:1425, glulx
            if ((!individual_property) && (property_number==1)
                && (token_type != SQ_TT) && (token_type != DQ_TT)
                )
                warning ("'name' property should only contain dictionary words");

I must have taken the extra clause out for some reason, but I can't remember why. Maybe I wanted to change the x// notation but then realized it would be too messy?

I'll fix them up to be parallel again unless someone can think of a reason that I did this.

Overly long name array corrupts object in z3

An object which has a name array longer than 4 dictionary words raises a warning when compiled to z3, and the compiler says it will truncate the array. But the object ends up corrupted.

This object:

Object -> Surfaceofthewater "Atlantic Ocean"
with name 'Surface' 'of' 'the' 'water', 'ocean', 'atlantic' 'ocean' 'sea' 'seawater' 'waves',
description "TODO",
before [; Enter: print "You enter the ocean...^"; ; rtrue;
];

Ended up like this in the story file (output from ztools/infodump):

  1. Attributes: None
    Parent object: 10 Sibling object: 14 Child object: 0
    Property address: 0be9
    Description: "Atlantic Ocean"
    Properties:
    [20] 44 59
    [ 4] 39 a5
    [ 1] 33 5b 30 3d
    [19] b6 34
    [18] 30 36 2a a9 30 36
    [18] 6d 32
    [27] 34 b9 00 0e
    [19] 34
    [20] 14 2c 7e
    [ 6] 9c 2a e0 1a
    [20] 4d 83 7b
    [23] 29 58
    [ 1] cb
    [ 1] 2a
    [23] 2d 00 05
    [ 4] a5 34 44 72 21 33
    [28] 30 3d 33 b6 34 11 2a 5c
    [19] b6 34
    [ 6] 2e a0
    [12] 9a 00
    [ 2] 13
    [13] 8b
    [ 5] 00 80

Property 20 get three different values. Some property values have length 1 or 3, something I believe the Inform compiler should never do.

Used Inform 6.34, the binary for Win32 available at if-archive, with the PunyInfom library.

Support -g3 (trace veneer routines)

The tech manual for 6.21 says:

The "-g" switch for tracing function calls now has a third setting, "-g3", which traces even veneer calls: the "-g2" setting now traces game and library calls but not veneer calls.

It looks like this made it into the code generator (there are tests for trace_fns_setting==3 in syntax.c and veneer.c) but not the argument parsing (inform.c). We could enable this.

This would require some amount of testing. Note that even -g2 will cause problems in Glulx, due to trying to print trace info before the output windows are opened. -g3 will certainly be worse.

Release tags, anyone?

You seem to have made some releases without tagging any of them. This makes archaeology, or even just figuring out what's been changed since the latest release, tricky.

Allow default language to be specified at compile time

It would be handy if the default language could be specified at compile time. Currently this is hardcoded here:

set_path_value(Language_Name, "English");
.

I'd do this by adding something like Default_Language to be checked in the same fashion as is done here:

set_path_value(Include_Path, Include_Directory);

However, if Default_Language is undefined, then English would be used instead.

My reason for this is that capitalization forces some gyrations with symlinks in a Unix environment to get things compiled. In https://gitlab.com/DavidGriffith/inform6unix I'm dealing with this by applying a patch to the Inform6 compiler code before compiling.

-b command line switch not mentioned anywhere

While working on #26, I noticed the -b command line switch. According to the source code it turns on bothpasses_switch. What is this? It's not mentioned in any of the -h usage information outputs.

Retire preallocation model and memory settings

As long as we're recording long-term goals... I always meant to replace all the preallocation limits (ALLOC_CHUNK_SIZE, etc) with realloc() calls.

I may never do this, but at least it's in the tracker now.

Related: There are many places where a bunch of parallel allocated arrays could be replaced by a single realloced array of structs. For example, symbs/svals/sflags/stypes/slines/smarks are all allocated with length MAX_SYMBOLS. Similarly, label_offsets/label_symbols/label_next/label_prev are all allocated with length MAX_LABELS. Structs would make this all easier to deal with.

AfterGameOver "RESTART" option doesn't call LibraryMessages

I have created thus

Object LibraryMessages
    with before [;
        Restart:
            print "Are you sure you want to restart? ";

            if (YesOrNo()){
               JSCommunication.RunCode("gameConsole.makeInformCall('Main', 'restart');");
            }     

            return true;
    ]
;

Which works reasonably well for overriding the restart command issued to the prompt.

However, the RESTART option provided in AfterGameOver (parser.h, line 5441), circumvents this. I have "corrected" this by changing line 5469 to if (~L__M(##Restart) == false) @restart; but I suspect this is not the correct overall solution.

Port to Julia?

I was looking at this and thinking it might be nice to port to Julia. I could do the work but I'd probably have to ask a lot of questions. Is that something people would be interested in?

DEBUG mode (-D) requires library support

This was discussed a while back:

https://intfiction.org/t/inform-6-error-when-compiling-with-d-without-the-library/45889

The -D option turns on the library's debug mode. (This dates from when the Inform compiler and library were always coupled.) The problem is that the veneer contains a lot of debug support that is meant to interact with the library, of the form:

#ifdef DEBUG;
if (debug_flag & FLAG) {
    ! argument safety checking
}
#endif;

The library must define the debug_flag global, or this will not compile. The library must also define the workflag attribute and the DebugAttribute() printing routine.

This leads to surprising errors if someone tries to compile, say, glulxercise.inf with -D on.

The current recommendation is "Don't do that." (glulxercise.inf has no debug features for the -D switch to turn on.) I think that's good enough, so this is not a high priority issue. But let's keep the issue on file.

<<X Y Z>> no longer works in z3

From Johan Berntsson:

I have discovered a bug in Inform6 and I want to ask if you can make sure that it is being fixed in a future upgrade.

I and some friends are making a new standard library for small computers (think Commodore 64) which is called PunyInform: https://github.com/johanberntsson/PunyInform We are testing this on both z3 and z5, while the Inform stdlib no longer works on z3. What I have discovered is that <> no longer works in z3. It doesn't return from the function as it is supposed to (the implicit rtrue isn't generated).

The problem is line 173 on states.c:
assemblez_4(call_zc, AO, AO2, AO3, AO4);
should instead be:
assemblez_4_to(call_zc, AO, AO2, AO3, AO4, temp_var1);

Since the temp_var1 is missing the next instruction (the rtrue) will be assumed to be a global variable location instead, so the rtrue is never executed, causing the problem (but only in z1-z3 of course; z5 etc works). I have recompiled the Inform compiler and confirmed that this change solves the problem.

I have attached the fixed and working states.c. Can you make sure that the fix finds its way into the official repository?
states.c.txt

Orphan code fragment

In some z3 story files, I get an orphan code fragment at the end of Zcode memory. This is what it looks like in "TXD -d -n" output:

orphan code fragment:

5006: 4e 97 e5 INSERT_OBJ G87,"lgwitsm"
5009: a5 62 INC [G52]
500b: 9a e5 PRINT_OBJ "lgwitsm"
500d: a5 28 INC [G18]
500f: d8 e4 a5 MOD -> G95
5012: 71 58 e4 a5 GET_PROP G48,Gd4 -> G95
5016: ea a5 26 9c cc a5 SPLIT_WINDOW G16,G8c,#cc,#a5
501c: ba QUIT

The code for this game contains a single SPLIT_WINDOW statement, and this is not it. This must be something which the compiler has thrown in.

I'm using the Inform 6.34 Win32 binary available at if-archive, with PunyInform.

Selecting desired library

Over at https://gitlab.com/DavidGriffith/inform6unix I'm experimenting with the idea of being able to select which library the author wants to use with a minimum of hassle. I've worked out a scheme that seems to work by requiring the use of a Makefile or else requiring the author to type in a long override of Include_Path by way of the +dir flag. I'd like to be able to do inform -L std foo.inf to compile something using the Standard library and inform -L puny bar.inf to use PunyInform. This would easily extend for any number of alternate libraries.

I envision this happening by reworking the *_path parameters that are compiled into the compiler. For instance, have lib_path contain /usr/local/share/inform/lib. Then in /usr/local/share/inform/lib would go subdirectories for whatever libraries desired. The -L flag would select what subdirectory to choose. So -L std would include files from /usr/local/share/inform/lib/std. Includes would be the same way: /usr/local/share/inform/include/std and so on because the includes mostly seem very library-specific.

How does this sound, at least in concept?

Better assembly output

The assembly trace (-a switch) produces lines like

call_vs      long_16 obj identifier -> x

This is really not very helpful, because "long_16" is an internal marker value which does not correspond to anything in the generated game file. (It might be the numeric constant 16, or veneer routine 16, or a routine with offset 16 in the code area, etc.) We could append a tag like "{veneer}", "{routine}", etc to distinguish these cases.

It would be even better to display the symbol which evaluated to the given constant. I think this would require adding a "symbol" field to the assembly_operand struct.

I don't believe anything relies on the -a output format, so adding this would not require a config setting.

Low priority, but maybe useful.

GCC 6 reports “implicit declaration of function ‘getpid’”

When compiling with GCC version 6, the compiler warns about an implicit function declaration:

$ gcc --version
gcc (Debian 6.1.1-11) 6.1.1 20160802
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ gcc -DUNIX64 -c -o inform.o inform.c
In file included from inform.c:11:0:
header.h: In function ‘unique_task_id’:
header.h:457:19: warning: implicit declaration of function ‘getpid’ [-Wimplicit-function-declaration]
 {   return (int32)getpid();
                   ^~~~~~

This indicates an existing problem (functions should be explicitly declared) that was not being reported by some earlier compiler versions.

Optimal abbreviation parsing

Not creating the optimal abbreviation list, but applying abbreviations optimally to each string as it is compiled. This is the try_abbreviations_from() function. It could be improved.

Code sample attached. This is Matt Russotto's C# implementation from this post: https://intfiction.org/t/highly-optimized-abbreviations-computed-efficiently/48753/46

optimalparse.txt

This involves repeatingly measuring the cost of a string with different abbreviations in place. (Cost meaning "length in Z-chars.") We might need a cut-down clone of translate_text() to do this efficiently.

Code generation optimizations

(As suggested in this thread: https://intfiction.org/t/next-steps-for-inform-6-compiler/51008)

For lines like

if (false) { return 97; }

...the compiler generates an unconditional jump, but then generates the return opcode anyway.

    3  +00011 <*> jump         to L0 
    4  +00017 <*> return       byte_97 
    5  +0001a    .L0

Ideally, the author would use #ifdef instead of if for this sort of code. However, I7 generates trivial conditions sometimes. E.g.

Understand "count [number]" as counting.

...generates the stanza:

    if (v == GPR_NUMBER) {
        n = noun; noun = parsed_number;
        if (~~(((true) && (true)))) v = GPR_FAIL;
        noun = n;
    }

The compiler successfully collapses (~~(((true) && (true)))) to (false) but still generates the v = GPR_FAIL; assignment.

This can almost be addressed with the execution_never_reaches_here flag, except that that flag is currently used to generate the "statement can never be reached" warning, which is not exactly the same thing. (See assembleg_1_branch(), which turns off that flag to avoid generating a warning on "if (false)..." because the author probably did it on purpose.) (I7 didn't do it on purpose, but I7 suppresses all warnings anyhow.)

I suspect the fix here is for execution_never_reaches_here to have three states: false, true, and "true but the author did it on purpose". If non-false, we can skip generating code entirely in assembleg_instruction() / assemblez_instruction().

(Is it safe to just bail out of those functions? What about inline strings in Z-code? Sequence points? Symbols used only in dead code? So many corner cases to check!)

Note that the compiler assumes that every jump label is live code, even if no jump statement goes there. (See assemble_label_no().) We should probably keep this. It allows the author to avoid dead-branch optimization on a case-by-case basis:

    if (false) { .KeepLive; return; }

(This might be needed for occult code generation techniques like inter-function jumps. Which we don't support, but maybe someone is trying to do it anyway.)

Better error messages when defining a function, attribute, property, etc

In the case where you say something like

Property foo;
Attribute foo;
[ foo; ... ];

...but "foo" is already defined, it would be good to report the location of the previous definition.

The compiler already does this if you write

Object obj with foo;
! implicitly defines a property foo

I am going to generalize that to the cases above.

Incorrect storage in dictionary?

Compile this with Inform 6.34, using -v3

Array buffer -> 100;
Array parse -> 100;


Object Being "human-like being"
	with
		name 'human' 'human-like' 'being';

[ Main i;
	print "Contents of Being.name:^";
	for(i=0 : i < (Being.#name / 2) : i++)
		print i, ": ", Being.&name-->i, "^";
	buffer->0 = 80;
	parse->0 = 20;
	@sread buffer parse;
	print "Contents of parse buffer:^";
	for(i=0 : i < parse->1 : i++)
		print i, ": ", (parse+0)-->(2 * i + 1), "^";
	@sread buffer parse;

];

Then run this in Windows Frotz and type this input: "human human-like being".

Apparently, human and human-like make two different dictionary words when compiling, but they are the same word when Windows Frotz looks up the words the player typed in the dictionary. I tried this in Gargoyle (Bocfel) too, with the same result.

The way I read the Z-machine spec ( https://www.inform-fiction.org/zmachine/standards/z1point1/sect03.html#seven ):

  • 'human' should be stored as first 'h' 'u' 'm' 'a' 'n' and then Z-character 5 as padding
  • 'human-like' should be stored as first 'h' 'u' 'm' 'a' 'n' and then Z-character 5 for shift (which should then be followed by Z-character 28 for '-' but that's truncated since we've run out of space)

So they should be identical as dictionary words, no?

ifdef limitation

Not sure how fixable this is, but it's a bit annoying and it can also lead to code compiled but not working as intended.

This doesn't compile:

[main a b;
#Ifdef FOO;
	if(a == b) print "Yes";
#Ifnot;
	if(a < b) print "Yes";
#Endif;
	else print "No";
];

By the time the compiler gets to "else" it doesn't remember the "if" context.

The following program compiles but it doesn't work as intended:

[main a b;
#Ifdef FOO;
	if(a == b)
#Ifnot;
	if(a < b)
#Endif;
 		print "Yes";
	print "Press a key: ";
	@read_char b;
];

print "Yes"; is performed regardless of the condition.

Better formatting for gametext.txt

The gametext.txt format is built for human proofreaders. You'd want a different format for a tool meant to construct an optimal abbreviation list.

The default should not change; the alternate format would be requested by a setting, $TRANSCRIPT_MARKERS=1.

I'm thinking every line starts with a three-character prefix:

I: Info (Transcript of the text of “Advent.inf”…)
G: Game text
V: Text in veneer
D: dictword
A: abbreviation
O: objectname

Update README to suggest better compilation options.

Trying again if you don't want a Makefile.

I've been working in open source development for a long time. It's considered polite to offer improvements to upstream.

So the README suggests:

cc -o inform *.c

This is bad advice. Inform 6 will run TWICE as fast if compiled with the -flto flag along with any level of optimization, with running time being cut in half on large test cases. The -flto flag has been available on both gcc and clang for over 10 years (it's documented in the manual for the 2011 releases). In short, a far more appropriate compilation command for practically all users of Unix-like systems in the last decade is

cc -flto -O2 -o inform *.c

And the best way to get this adopted downstream is to get it documented in the upstream repository. I strongly advise that this information be put in the README.

I have found four different downstream packages packaging and compiling inform6 from this upstream (gnome-inform7, inform7 CLI, Inform 6 for Unix, and the Debian Inform 6 package), each with its own hand-spun build system, and not one of them does this. There are probably more. While I have contacted all of their maintainers, I have not gotten a response yet. This ought to be documented upstream.

Non-case code in switch blocks is ignored

Example (which just recently caused me some headache):

switch (event){
  EVENT1:
    event1();
  EVENT2:
    event2();
  default:
    unknownEvent(event);

  return event; <- This is inside the switch, it does nothing and is not reported by the compiler
}

Perhaps there's a reason for being able to do this and that's why the compiler doesn't complain.

`remove_temp_files` & `unlink_temp_files`

I'm trying to compile the current commit of Inform6 for EPOC32 which limits me to VC6 and an ancient version of GCC that don't support C99. There weren't many problems! A few variables not defined at the beginning of a scope, and snprintf is missing, but I noticed something unusual that might not be related to C89/C99: "inform6.c" calls remove_temp_files from "files.c", but that function doesn't exist, only unlink_temp_files! This is easily fixed for me, but I wonder if this is supposed to be this way?

Support MAX_ABBREVS in Z-code

Currently the compiler always reserves 32 of the Z-machine's 96 abbreviations for dynamic strings. (These look like @00 to @31 in string literals, and can be modified with the string statement.) The other 64 are abbreviations (the Abbreviate directive).

It would be good to allow the user to trade these off -- up to 96 of either.

I propose doing this with the MAX_ABBREVS compiler setting. This already exists, and defaults to 64 for Z-code. I'll limit this to the range 0..96. The compiler will assume that 96-MAX_ABBREVS dynamic strings are available.

Fussy details:

Setting MAX_ABBREVS=100 is currently legal in Z-code. It's pointless, since the compiler is hardwired to throw an error beyond 64 abbreviations. So I'm pretty sure nobody does it. If they do, they'll get a sensible error message in the future.

Currently the dynamic string range is completely unchecked in Z-code. You can put any number up to @99 into a string literal; its value is interpreted mod 32. You can pass any number to a string NUM "foo" statement; values beyond 31 will stomp on low memory. Oops.

I intend to add compile-time bounds checking and error messages where possible. string EXPR "foo" where expr is not a constant would require run-time bounds checking, but I don't want to add runtime code for this corner case, so people will have to continue living with it.

Alter command line options to remove dollar signs

As I wrapped up version 6.12.4 of the Standard Library, I looked again at the list of accepted suggestions at http://inform-fiction.org/suggestions/accept.html. One of them has bothered me for a long time: The Inform6 compiler still makes use of dollar signs on the command line. To fix this, someone suggested and apparently Graham accepted the suggestion. Here it is:

  1. The use of "$..." to introduce compiler options is intensely annoying on *NIX systems that use "$" as an environment variable indicator, e.g. $PATH -- it requires the constant use of quotes to avoid unpleasant and confusing results.

Is this something that can be considered again?

Make INDIV_PROP_START a memory setting

A patch to make INDIV_PROP_START configurable as a memory setting, following Andrew Plotkin's paragraph in his glulx-technical.txt:

The value of INDIV_PROP_START is currently hardwired to 256, in the
compiler. It will eventually be made flexible. The veneer and library
use the constant INDIV_PROP_START, so they can adapt to any value the
compiler defines.

jessepav@2a9cf26

Extra copies of dictionary words in z3

If you compile a game to z3, and there are two dictionary words in the source code which are not different with the six-character resolution of z3, but would be different if the resolution was 9 characters as in z5, they are created as separate dictionary words, which causes all sorts of problems. Example:

Object Scorpion "scorpion"
with
name 'scorpionx' 'scorpiony';

This creates two dictionary words: 'scorpi' and 'scorpi' (truncated to six characters). Depending on the interpreter's method of searching the dictionary, one or the other may be matched when the player type a word beginning with scorpi.

Undeclared constant not detected by the compiler

The compiler does not detect that the constants for the Dictionary directive are not declared. However, it assigns them a value.

Dictionary 'word' DICT_XXX DICT_YYY;
[ main;
   print ('word'->#dict_par1), "^";
   print ('word'->#dict_par3), "^";
];
162
35

(instead of 128, 0)

Stop automatically setting -D when you set -k?

I was trying to compile Glulxercise with the -k option, and Inform gives this error:

"<constructing output>", line 0: Error:  No such constant as "debug_flag"

This seems to come from the veneer's use of debug_flag.

I don't know what the best thing to do is, but this feels quite nonoptimal to me.

Would it be possible to insert this code if the -k flag is used?

#ifndef debug_flag;
Global debug_flag = 0;
#endif;

I've added this to Glulxercise and it now compiles, but it says that debug_flag isn't used, so I guess it's not detecting its use by the veneer?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.