GDCC: An Alternative ACS Compiler [0.15.0]

Any utility that assists in the creation of mods, assets, etc, go here. For example: Ultimate Doom Builder, Slade, WadSmoosh, Oblige, etc.
Forum rules
The Projects forums are ONLY for YOUR PROJECTS! If you are asking questions about a project, either find that project's thread, or start a thread in the General section instead.

Got a cool project idea but nothing else? Put it in the project ideas thread instead!

Projects for any Doom-based engine (especially 3DGE) are perfectly acceptable here too.

Please read the full rules for more details.
Post Reply
User avatar
DavidPH
Posts: 382
Joined: Fri Aug 28, 2009 1:46 pm

GDCC: An Alternative ACS Compiler [0.15.0]

Post by DavidPH »

GDCC, The Game Data Compiler Collection. With respect to ZDoom, it is simply an alternative compiler for ACS bytecode to replace DH-acc. It features a largely complete C11 compiler that can target ZDoom and Zandronum 3.x.

Given that C is specified in an international standard, I do not think an exhaustive list of features over ACS is required, but here are some big ones:
  • Advanced flow control using setjmp/jongjmp.
  • IEEE single and double precision floating-point types and a nearly complete math.h implementation.
  • Data structures, including unions and fully-featured C99 initializer syntax.
  • 64 and 96 bit integer types. As well as an extended s31.32 fixed-point type.
  • Pointers to both objects and functions.
  • Short-circuiting logical expressions.
  • Fully-featured C-preprocessor.
  • Embedded C address spaces in order to make use of map/world/global variables/arrays.
  • Scripts can be called like functions, and extra arguments are passed automatically.
  • Special "synchronous script" calling convention that causes the caller to wait for the callee to return.
GDCC also has an ACS front, meant to be compatible with acc. It supports Zandronum 2.0. It also features some extensions:
  • Structure types, using a pared down C syntax.
  • Enumerations, with C syntax.
  • Proper fixed types, enabled by pragma.
  • Proper C object-like macros, enabled by pragma.
  • Function-like macros.
  • Script/function variables are properly scoped to the block they are declared in, enabled by pragma.
Spoiler: Quick Start Guide
Wiki: http://gdcc.greyserv.net/Main_Page
Source: https://github.com/DavidPH/GDCC
Windows builds: https://www.dropbox.com/sh/5wae0ro7vues ... S3qHa?dl=0
Discord server: https://discord.gg/zjydTej
Last edited by DavidPH on Mon Feb 25, 2019 12:50 pm, edited 22 times in total.
User avatar
CommanderZ
Posts: 210
Joined: Sun Nov 14, 2010 8:23 am
Location: Czech Republic
Contact:

Re: [WIP] DH-acc: ACS C Compiler

Post by CommanderZ »

Wow, I was thinking of doing exactly this myself, so thumbs up!

What I am missing the most in ACS (which are I believe in your scope):

- structs
- proper arrays (which would work as local variables, function parameters or return values), dynamic arrays
- ability to implement data structures such as linked lists and simple trees (you seem to have handled this by inclusion of pointers)
- preprocessor macros (this can be easily worked around by using separate preprocessor - I use mcpp for this)
- function types + anonymous functions (so you can have a variable/parameter which takes a function + is able to call the function on parameters of its choice) - this might be already possible with script numbers, but is too cumbersome to use
- proper math library (sqrt, log, atan, pow)
- 64bit math
- dynamic string manipulation (something seems to be happening in ZDoom on this front lately, but this does't quite help yet, because it requires SVN versions)
- foreach statement
- module discovery/namespaces (text-based inclusion is sooo from 90s :), figuring working order of functions is sometimes quite a challenge in ACS currently

Some of these are definitely not really necessary, but still would make mod development experience much more pleasant one :)

What is really necessary are the struct and array related features. I still get shivers every time I look at my macro-based matrix math functions (it failed to figure out any other way of implementing matrix function without structs and arrays).

Structs + function types would make a proper GUI library a possibility, which would also be a huge leap forward.

Math functions can be emulated within ACS, but those are inefficient and/or inaccurate parodies on real math.



And some which I think are not in your scope:

- ability to retrieve string information about actors and weapons (such as class name or tag)
- proper identification of actors beyond TID, comparison of actors
- enumeration of actors based on some criteria (primarily actors within range of a point)

I touched some of these in my preprocessor (actor identification and enumeration, string actor properties, custom actor properties), but there is only so much you can do with regex-based analysis and generation of ACS and DECORATE code.\

Good luck with your project!

EDIT:

I had a look at the repo you linked.

You started from some existing C parser?

Also, from the actual scripts you included, it seems you are going for some horribly convoluted syntax elements.

Code: Select all

__extfunc memcpy(void *restrict s1, void const *restrict s2, size_t n) -> void *
{
   __variable __autoreg char const *end = (char const *)s2 + n;

   __variable __autoreg char       *i1 = (char       *)s1;
   __variable __autoreg char const *i2 = (char const *)s2;

   while (i2 != end)
   {
      *i1++ = *i2++;
   };

   return s1;
};
I don't think even Managed C++ spammed double underscores so much :)

I also don't understand why you decided for that exact return type syntax you are using, assuming everything else seems to be pretty much exact C.

I personally hoped for a bit more higher-level (like C# or Java) approach but I guess with some work, this can still be much better than ACS.

Does the thing you've got generate some ZDoom bytecode already? I can't find anything code generation related in the code :)

EDIT2:
DH-acc uses a completely different language, DamnScript, which operates at a higher level than ACS.
Are you sure "higher" is the word? All the DS heap managment code and gazillion pointers make me think exact opposite :D
Last edited by CommanderZ on Sun Feb 26, 2012 2:21 pm, edited 5 times in total.
User avatar
Apothem
Posts: 2070
Joined: Sat Nov 29, 2003 7:13 pm
Location: Performing open heart surgery on an ACS compiler.

Re: [WIP] DH-acc: ACS C Compiler

Post by Apothem »

Simply being able to use this on something more than just ZDoom would be epic. I know there are a lot of source ports out there that actually already use a form of ACC, however I am sure that if this were to be done right, and you could probably get this to work for *shudder* zdaemon :P
User avatar
DavidPH
Posts: 382
Joined: Fri Aug 28, 2009 1:46 pm

Re: [WIP] DH-acc: ACS C Compiler

Post by DavidPH »

I'll take these one at a time...
CommanderZ wrote:- structs
[Already In] :P
CommanderZ wrote:- proper arrays (which would work as local variables, function parameters or return values),
DS has array types, and they can be passed/returned by value.
CommanderZ wrote:dynamic arrays
stdlib.ds has a working implementation of malloc.
CommanderZ wrote:- ability to implement data structures such as linked lists and simple trees (you seem to have handled this by inclusion of pointers)
Yeah, that's a job for pointers.
CommanderZ wrote:- preprocessor macros (this can be easily worked around by using separate preprocessor - I use mcpp for this)
Macros are a planned feature of the preprocessor. Simple defines are already in, however.
CommanderZ wrote:function types + anonymous functions
Functions are handled by the type system and a function can be defined anywhere an expression is allowed. (Which is everywhere.) However...
CommanderZ wrote:variable/parameter which takes a function
Calling function-pointers is not really feasible with the current engine. (Even a work-around would have deficiencies because of how functions are addressed.) However! You can call scripts like functions. And when called from DS code, they can have any number of arguments.
CommanderZ wrote:- proper math library (sqrt, log, atan, pow)
math.ds is now on the TODO list.
CommanderZ wrote:- 64bit math
I'm actually working on this a little.
CommanderZ wrote:- dynamic string manipulation (something seems to be happening in ZDoom on this front lately, but this does't quite help yet, because it requires SVN versions)
As far as manipulation is concerned, there is a char type you can have pointers to. However, as far as passing those back into the engine, that requires those engine extensions.
CommanderZ wrote:- foreach statement
I'd rather not touch on this without either classes or references. (Both of which are things I'd like to have.)
CommanderZ wrote:- module discovery/namespaces (text-based inclusion is sooo from 90s :), figuring working order of functions is sometimes quite a challenge in ACS currently
Welcome to the 90s, then. :P Actually, C++ namespaces are also something I'd like to do at some point. However, header inclusion will always be explicit. DS has forward declaration, though.
CommanderZ wrote:Math functions can be emulated within ACS, but those are inefficient and/or inaccurate parodies on real math.
Unfortunately, there is little I can do in this regard.

The remaining items are not beyond my scope, but do require engine support.

(Now to address your edit that you made after I started writing this.)
My original plan was to write a C compiler, but I never figured out how to read actual C code so I wrote DS instead. As for the convolution: I'm thinking of how best to handle a shorter variable declaration syntax. That said, you can use the preprocessor to shorten things up. My test script, for instance, uses #define var __variable # to great effect. And the reason for the return syntax is that it was what I could manage to parse. Besides, it's good enough for C++11.

As for your suggestion that I do something akin to C#/Java: I don't know C#. I don't like Java because it's not as fast to execute as C/C++. I doubly don't like C# because it has nothing to do with C. If you're asking for a garbage collected language, then that is outside of the scope of this project.

(Re: Edit1.1)
SourceTokenZDACS.

(Re: Edit2)
Yeah, it's higher level than ACS. Some people forget that C is in fact a high-level language and it offers a considerably abstracted view of the machine. The thing is, it does this without actually separating from the machine.

Apothem wrote:zdaemon
If it uses straight Hexen ACS, then failure to do codegen for it is a bug. If it has extended features, provide specs and I'll add TARGET_ZDaemon.
User avatar
printz
Posts: 2648
Joined: Thu Oct 26, 2006 12:08 pm
Location: Bucharest, Romania
Contact:

Re: [WIP] DH-acc: ACS C Compiler

Post by printz »

OMFG, Project Blackfire and now this? Marvelous! Even though Damnscript sounds like a swearword, I'm quite looking forward to this. Can it compile into plain Hexen BEHAVIOR so it's not ZDoom exclusive?
User avatar
DavidPH
Posts: 382
Joined: Fri Aug 28, 2009 1:46 pm

Re: [WIP] DH-acc: ACS C Compiler

Post by DavidPH »

Yes. If you find an ACS engine that DH-acc cannot correctly target, that is a bug. By the way, DH-acc defaults to targeting Hexen.
User avatar
CommanderZ
Posts: 210
Joined: Sun Nov 14, 2010 8:23 am
Location: Czech Republic
Contact:

Re: [WIP] DH-acc: ACS C Compiler

Post by CommanderZ »

Calling function-pointers is not really feasible with the current engine. (Even a work-around would have deficiencies because of how functions are addressed.) However! You can call scripts like functions. And when called from DS code, they can have any number of arguments.
This could be at least emulated in some way (I think I would even be able to do this with the preprocessor, but I only wrote Decorate parser so far) - you have to assign some ID to each function (which would be passed around as the function pointer) and then make a simple router function, which would look at the ID which it got and decide which function to call and pass the parameters. You would then call this router function on every place where function pointer is dereferenced.

With some hackery, this should be possible without walking through every ID.

By anonymous function, I meant a function which can be declared mid-expression. But that isn't all that necessary (and there are some hidden challenges in this, like variable capturing).
Welcome to the 90s, then. Actually, C++ namespaces are also something I'd like to do at some point. However, header inclusion will always be explicit. DS has forward declaration, though.
But why? There is no dynamic linkage, (hopefully) module compilation etc.

I'm quite sure you could do without headers and forward declarations - just make the function callable if it is defined somewhere in the code.

Headers and forward declarations are the single most painful thing about C++ and C (along with lack of templates in C).

BTW, what about templates :D


By C# and Java, I didn't exactly mean garbage collection. I meant code organization (namespaces and usings instead of headers).

EDIT:
My original plan was to write a C compiler, but I never figured out how to read actual C code so I wrote DS instead.
Do you know there are parser generators such as Flex + Bison? You feed those with formal declarations of tokens and grammar (you can find ANSI C grammar for Bison here) and they generate the C parser code for you. Writing a C parser with this isn't all that hard - of course you have yet to fill in the compiler parts, but that isn't that hard either (I personally never wrote C compiler, only Pascal-ish one, but that isn't all that different from C). Your parser seems rather ad-hoc, which is probably source of your trouble.
Last edited by CommanderZ on Sun Feb 26, 2012 3:26 pm, edited 1 time in total.
Gez
 
 
Posts: 17833
Joined: Fri Jul 06, 2007 3:22 pm

Re: [WIP] DH-acc: ACS C Compiler

Post by Gez »

Compiling C into ACS bytecode is just the first step. Then you've got to compile C++ into ACS bytecode, and finally get ZDoom to run inside Hexen.
User avatar
printz
Posts: 2648
Joined: Thu Oct 26, 2006 12:08 pm
Location: Bucharest, Romania
Contact:

Re: [WIP] DH-acc: ACS C Compiler

Post by printz »

Gez wrote:and finally get ZDoom to run inside Hexen.
Speaking of things like this, will this BEHAVIOR progress lead to being able to do more than listed here: [wiki]Built-in ACS functions[/wiki]
User avatar
DavidPH
Posts: 382
Joined: Fri Aug 28, 2009 1:46 pm

Re: [WIP] DH-acc: ACS C Compiler

Post by DavidPH »

Functions already are by index. And I already know how I'd emulate function-pointers when targeting ZDoom. The problem is that the exact index differs between each loaded BEHAVIOR module, so you couldn't pass them around arbitrarily. Don't forget that ACSE allows runtime-combining of BEHAVIOR modules. On that note:

ACSE/e is dynamic linkage. The moment I realized this was the moment I was able to start working with it properly. Also, DH-acc supports module compilation. Static linkage is still the only way to use certain features effectively with ZDoom.

Templates are something I'd like, but that requires function overloading, first. And that style of anonymous functions is sort of supported. You can define a function in another function, but there's no special semantics. It's just a convenient place to stash code.

As for "just" making it callable if it's defined anywhere... How do I know it's defined somewhere? What if it's defined in a different ACSE module? Or even just a different file? How does that play nicely with function overloading and other name-mangling concerns? What if the function being called is a template?

And yes, I know of parser generators. And I know there are existing definitions for C. But that leaves two problems. Firstly, and most simply, I prefer my own code. I'll use a fully external library, but I'm not comfortable with the build process of generating code. Secondly, because as I learned while writing DS: C is unsuited to targeting the ACS VM. Something as simple as script types would require syntax far worse than my variable declarations. Or what about storing variables in mapregisters of worldarrays or etc. C's semantics, however, feel quite at home. So I cherry-picked.

On the note of the parser being entirely ad-hoc: It is entirely ad-hoc, so if there's any shred of it seeming planned, then I choose to accept that as a compliment.
User avatar
CommanderZ
Posts: 210
Joined: Sun Nov 14, 2010 8:23 am
Location: Czech Republic
Contact:

Re: [WIP] DH-acc: ACS C Compiler

Post by CommanderZ »

Is there any particular reason why you would want to do module compilation?

My preprocessor executed on RGH produces single about 50k-line ACS file and it works just fine ingame, I don't observe any lags or extended loading times, compilation is still instantaneous, and ACS files aren't going to get much bigger than that. I don't see a single reason why you would want to bring in unnecessary complexity.
Something as simple as script types would require syntax far worse than my variable declarations.
Why? C already has things like calling conventions or GCC attributes, which allow you to add additional information to function (that said, GCC attribute syntax is very unpleasant, I'm just making a point).

I personally would like to see syntax syntax closer to C# attributes:

Code: Select all

[Respawn]
void handleRespawn(){

}
User avatar
printz
Posts: 2648
Joined: Thu Oct 26, 2006 12:08 pm
Location: Bucharest, Romania
Contact:

Re: [WIP] DH-acc: ACS C Compiler

Post by printz »

I wonder if this architecture can be put to good use to make some highly dynamic Strife* RPG worlds, where every person is an individual with a life, or at least a name.
User avatar
DavidPH
Posts: 382
Joined: Fri Aug 28, 2009 1:46 pm

Re: [WIP] DH-acc: ACS C Compiler

Post by DavidPH »

Static variable allocation. Hell, all the deferred allocation stuff. Also, you're not really making a fair comparison on compile times. Yes, acc compiles fast. It also has very minimal processing of the source. It doesn't do even basic optimization. Besides, the object stuff already exists in order to abstract each target's instruction set. Doing the output/input on it was very little code. (Because the output is not portable and probably never will be. It's an intermediate format invalidated any time I update the program.) Besides, the alternative is to pile everything into one file using #include, which means you can't invoke module-private names. (C's file-scope static.)

And my point regarding script type was that it would require unwieldy syntax, not that it couldn't be done. The unstated part was also that it's not ANSI C. (I might add that ANSI C does not in fact have a concept of calling convention. All functions are created equal.)

To do that C# syntax requires a radically different parser. Even if I was willing to use someone else's parser or parser generator, the way such source is parsed leaves it open to far more subtle gotchas and nuances than I want to deal with.
CommanderZ wrote:I don't see a single reason why you would want to bring in unnecessary complexity.
I don't. That's why I don't have an actual C parser. That's why everything in DS is an expression. That's why you have to forward declare functions. That's why #include is used. That's why dozens of things in DH-acc/DS are the way they are. Because I avoid unnecessary complexity.
User avatar
Apothem
Posts: 2070
Joined: Sat Nov 29, 2003 7:13 pm
Location: Performing open heart surgery on an ACS compiler.

Re: [WIP] DH-acc: ACS C Compiler

Post by Apothem »

Gez wrote:Compiling C into ACS bytecode is just the first step. Then you've got to compile C++ into ACS bytecode, and finally get ZDoom to run inside Hexen.
Wouldnt this be something along the lines of dividing the universe by 0? I mean there is already a mod for doom3 that runs doom2 off of an arcade machine inside the game.

Having zdoom run in hexen would just make my head hurt.
User avatar
DavidPH
Posts: 382
Joined: Fri Aug 28, 2009 1:46 pm

Re: [WIP] DH-acc: ACS C Compiler

Post by DavidPH »

And thankfully quite impossible. No amount of compiler support would get around the fact that Hexen offers less than a kilobyte of memory to ACS. (Believe me, I've thought about emulating pointers in vanilla. It's possible, but not worthwhile.)
Post Reply

Return to “Creation, Conversion, and Editing”