Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #100994 > unrolled thread

'Amalgamated' source code

Started byBartC <bc@freeuk.com>
First post2017-01-03 15:14 +0000
Last post2017-04-26 07:17 -0700
Articles 20 on this page of 54 — 12 participants

Back to article view | Back to comp.lang.c


Contents

  'Amalgamated' source code BartC <bc@freeuk.com> - 2017-01-03 15:14 +0000
    Re: 'Amalgamated' source code Thiago Adams <thiago.adams@gmail.com> - 2017-01-03 08:47 -0800
      Re: 'Amalgamated' source code BartC <bc@freeuk.com> - 2017-01-03 19:47 +0000
        Re: 'Amalgamated' source code Thiago Adams <thiago.adams@gmail.com> - 2017-01-03 12:48 -0800
          Re: 'Amalgamated' source code BartC <bc@freeuk.com> - 2017-01-03 21:36 +0000
            Re: 'Amalgamated' source code Thiago Adams <thiago.adams@gmail.com> - 2017-01-03 16:01 -0800
              Re: 'Amalgamated' source code Keith Thompson <kst-u@mib.org> - 2017-01-03 16:26 -0800
                Re: 'Amalgamated' source code Thiago Adams <thiago.adams@gmail.com> - 2017-01-03 18:00 -0800
                  Re: 'Amalgamated' source code Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-04 03:34 +0000
                    Re: 'Amalgamated' source code Thiago Adams <thiago.adams@gmail.com> - 2017-01-04 03:31 -0800
                      Re: 'Amalgamated' source code BartC <bc@freeuk.com> - 2017-01-04 12:03 +0000
                        Re: 'Amalgamated' source code Thiago Adams <thiago.adams@gmail.com> - 2017-01-04 05:00 -0800
                          Re: 'Amalgamated' source code Thiago Adams <thiago.adams@gmail.com> - 2017-01-05 02:38 -0800
                            Re: 'Amalgamated' source code Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-05 14:28 +0000
                              Re: 'Amalgamated' source code supercat@casperkitty.com - 2017-01-05 08:20 -0800
                                Re: 'Amalgamated' source code Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-05 17:05 +0000
                                  Re: 'Amalgamated' source code supercat@casperkitty.com - 2017-01-05 10:11 -0800
                                    Re: 'Amalgamated' source code Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-05 19:46 +0000
                                      Re: 'Amalgamated' source code Thiago Adams <thiago.adams@gmail.com> - 2017-01-05 12:15 -0800
                                        Re: 'Amalgamated' source code Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-05 21:54 +0000
                              Re: 'Amalgamated' source code BartC <bc@freeuk.com> - 2017-01-05 17:40 +0000
                                Re: 'Amalgamated' source code Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-05 19:33 +0000
              Re: 'Amalgamated' source code BartC <bc@freeuk.com> - 2017-01-04 10:53 +0000
            Re: 'Amalgamated' source code Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-04 01:51 +0000
          Re: 'Amalgamated' source code BartC <bc@freeuk.com> - 2017-01-04 11:54 +0000
            Re: 'Amalgamated' source code Thiago Adams <thiago.adams@gmail.com> - 2017-01-04 05:57 -0800
              Re: 'Amalgamated' source code BartC <bc@freeuk.com> - 2017-01-04 14:20 +0000
              Re: 'Amalgamated' source code BartC <bc@freeuk.com> - 2017-01-04 15:07 +0000
                Re: 'Amalgamated' source code Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-04 15:34 +0000
                  Re: 'Amalgamated' source code Thiago Adams <thiago.adams@gmail.com> - 2017-01-04 08:03 -0800
                    Re: 'Amalgamated' source code Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-04 17:09 +0000
                  Re: 'Amalgamated' source code bart4858@gmail.com - 2017-01-04 08:54 -0800
                    Re: 'Amalgamated' source code Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-04 17:22 +0000
                Re: 'Amalgamated' source code Thiago Adams <thiago.adams@gmail.com> - 2017-01-04 07:55 -0800
                  Re: 'Amalgamated' source code BartC <bc@freeuk.com> - 2017-01-05 18:04 +0000
                    Re: 'Amalgamated' source code Thiago Adams <thiago.adams@gmail.com> - 2017-01-05 11:50 -0800
    Re: 'Amalgamated' source code Jorgen Grahn <grahn+nntp@snipabacken.se> - 2017-01-04 16:29 +0000
      Re: 'Amalgamated' source code bart4858@gmail.com - 2017-01-04 09:15 -0800
        Re: 'Amalgamated' source code Ian Collins <ian-news@hotmail.com> - 2017-01-05 08:33 +1300
          Re: 'Amalgamated' source code BartC <bc@freeuk.com> - 2017-01-04 20:26 +0000
            Re: 'Amalgamated' source code supercat@casperkitty.com - 2017-01-04 13:09 -0800
            Re: 'Amalgamated' source code Ian Collins <ian-news@hotmail.com> - 2017-01-05 10:21 +1300
              Re: 'Amalgamated' source code supercat@casperkitty.com - 2017-01-04 13:51 -0800
              Re: 'Amalgamated' source code BartC <bc@freeuk.com> - 2017-01-04 22:02 +0000
                Re: 'Amalgamated' source code Ian Collins <ian-news@hotmail.com> - 2017-01-05 11:15 +1300
        Re: 'Amalgamated' source code Jorgen Grahn <grahn+nntp@snipabacken.se> - 2017-01-07 06:38 +0000
          Re: 'Amalgamated' source code BartC <bc@freeuk.com> - 2017-01-07 11:35 +0000
      Re: 'Amalgamated' source code supercat@casperkitty.com - 2017-01-04 09:53 -0800
      Re: 'Amalgamated' source code Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-01-04 11:50 -0800
      Re: 'Amalgamated' source code raltbos@xs4all.nl (Richard Bos) - 2017-01-10 01:34 +0000
        Re: 'Amalgamated' source code Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-01-10 01:59 -0800
        Re: 'Amalgamated' source code Les Cargill <lcargill99@comcast.com> - 2017-01-10 06:55 -0600
        Re: 'Amalgamated' source code Richard Heathfield <rjh@cpax.org.uk> - 2017-01-10 14:48 +0000
    Re: 'Amalgamated' source code Thiago Adams <thiago.adams@gmail.com> - 2017-04-26 07:17 -0700

Page 1 of 3  [1] 2 3  Next page →


#100994 — 'Amalgamated' source code

FromBartC <bc@freeuk.com>
Date2017-01-03 15:14 +0000
Subject'Amalgamated' source code
Message-ID<o4gf2a$bl9$1@dont-email.me>
Interesting article here on converting large projects into just a few 
source files:

https://blog.forrestthewoods.com/improving-open-source-with-amalgamation-cf293592c5f4#.jzgq6ppvn

It's something I could do with because I always have trouble compiling 
open source projects. Especially now as I'm looking for test input to 
try out my tools on.

I do it myself when distributing some of projects, but it's a laborious 
set of manual steps.

(My new C processor ought to be able to do it automatically, but the 
starting point must be code that already compiles conventionally. Such 
projects are in short supply! Large projects anyway.

I've got a single file, 800Kloc version of gcc [for the 'cc1' module], 
but it doesn't compile under gcc! But then it has Linux dependencies, so 
maybe I can take care of those.)

-- 
Bartc

[toc] | [next] | [standalone]


#101010

FromThiago Adams <thiago.adams@gmail.com>
Date2017-01-03 08:47 -0800
Message-ID<dbf92bb2-ae2d-4133-83f6-f0f9a5c5d198@googlegroups.com>
In reply to#100994
On Tuesday, January 3, 2017 at 1:14:53 PM UTC-2, Bart wrote:
> Interesting article here on converting large projects into just a few 
> source files:
> 
> https://blog.forrestthewoods.com/improving-open-source-with-amalgamation-cf293592c5f4#.jzgq6ppvn
> 
> It's something I could do with because I always have trouble compiling 
> open source projects. Especially now as I'm looking for test input to 
> try out my tools on.
> 
> I do it myself when distributing some of projects, but it's a laborious 
> set of manual steps.
> 
> (My new C processor ought to be able to do it automatically, but the 
> starting point must be code that already compiles conventionally. Such 
> projects are in short supply! Large projects anyway.
> 
> I've got a single file, 800Kloc version of gcc [for the 'cc1' module], 
> but it doesn't compile under gcc! But then it has Linux dependencies, so 
> maybe I can take care of those.)
> 
> -- 

Hi, I like the concept of one-unit of compilation.
(I also have implemented an C preprocessor.)
I think there are two options to generate this amalgamation.

1) Mechanic form
 - Just merge files avoiding to include header files more than once.
 - Programmer needs to avoid name conflicts for the internal linkage functions. (let's say there are two static void F())
 - "system" or "external headers" are not included.
 - Programmer can create a macro PRIVATE that can be 
defined as static for the amalgamate and empty for normal 
development using multiple files.

2) " Transpilation" - generate C code
Read many C files and generates one file doing what is necessary to avoid internal linkage conflicts.

The generated code also could transform functions into static 
to make internal linkage if they are not "exported".

I was playing with this idea because I wanted to use my parser to extend the C language but generating one ANSI C file.

Let's say I want to implement the default initialization in a extended C language.

--file1.h--
#include <stdio.h>

struct X {
 int i = 1;
};

--file1.c--

#include "file1.h" 
void f()
{
  struct X x = {};
}

----------
Then the generated C file would be:

#include <stdio.h>

struct X {
 int i;
};

void f() {
  struct X x = {1};
}


Note that because I changed the declaration I cannot include file1.h but I still including system files <stdio.h>
For static function inside many files I would have to rename each function when generating one file

For instance:

--file1.c--

static void F() { }

void F2() {   F(); }

--file2.c--

static void F() {}

void F3() {  F(); }

--
merged file

static void _FILE1_F() { }
void F2() {   _FILE1_F(); }

static void _FILE2_F() { }

void F3() { _FILE2_F();}


---

More references:

https://www.sqlite.org/amalgamation.html

https://github.com/vinniefalco/Amalgamate

[toc] | [prev] | [next] | [standalone]


#101024

FromBartC <bc@freeuk.com>
Date2017-01-03 19:47 +0000
Message-ID<o4gv18$8sc$1@dont-email.me>
In reply to#101010
On 03/01/2017 16:47, Thiago Adams wrote:
> On Tuesday, January 3, 2017 at 1:14:53 PM UTC-2, Bart wrote:
>> Interesting article here on converting large projects into just a few
>> source files:
>>
>> https://blog.forrestthewoods.com/improving-open-source-with-amalgamation-cf293592c5f4#.jzgq6ppvn

> Hi, I like the concept of one-unit of compilation.
> (I also have implemented an C preprocessor.)

(I'm the middle of one at the minute. Most online refs on writing 
compilers tend to ignore this piffling little obstacle that you have to 
overcome first!)

> I think there are two options to generate this amalgamation.

> 2) " Transpilation" - generate C code
> Read many C files and generates one file doing what is necessary to avoid internal linkage conflicts.
>
> The generated code also could transform functions into static
> to make internal linkage if they are not "exported".
>
> I was playing with this idea because I wanted to use my parser to extend the C language but generating one ANSI C file.
>
> Let's say I want to implement the default initialization in a extended C language.
>
> --file1.h--
> #include <stdio.h>
...
> #include "file1.h"
...

>Then the generated C file would be:
>
> #include <stdio.h>
>
> struct X {
>  int i;
> };
>
> void f() {
>   struct X x = {1};
> }
>
>
> Note that because I changed the declaration I cannot include file1.h but I still including system files <stdio.h>
> For static function inside many files I would have to rename each function when generating one file

> --file1.c--
>
> static void F() { }
>
> void F2() {   F(); }
...
> merged file
>
> static void _FILE1_F() { }
> void F2() {   _FILE1_F(); }

This is like the approach I use at the minute, but part of a project 
where non-C source is converted to C, still a module at a time. A 
special compile option is used to change how declarations are generated 
and how global names are treated (by adding prefixing, but I'm also 
experimenting with no prefix, and manually avoiding clashes, as 
otherwise the output looks horrific. Or more horrifix!).

In this form, it can't be processed a C compiler as normal. A separate 
step is needed that scans all the modules, and collates the blocks of 
code, so that all type declarations, all variables etc are grouped 
together at the top of the file. (Example 
https://github.com/bartg/langs/blob/master/pcc.c)

It's a bit of a pain (and there are complications to do with the target 
OS where the right modules have to be picked). I'll be glad when my new 
C to C translator works then it'll be automatic.

 > https://www.sqlite.org/amalgamation.html

I wonder why other open source products don't take the same approach? 
Sometimes people just aren't interested in the details of how a project 
is structured, they just want to compile whatever source code is needed 
and end up with an executable, without any fuss, or having to install 
half of Unix.

-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#101032

FromThiago Adams <thiago.adams@gmail.com>
Date2017-01-03 12:48 -0800
Message-ID<f878a326-cda4-491f-be4c-65977eb7d1e9@googlegroups.com>
In reply to#101024
On Tuesday, January 3, 2017 at 5:47:24 PM UTC-2, Bart wrote:
> On 03/01/2017 16:47, Thiago Adams wrote:
> > On Tuesday, January 3, 2017 at 1:14:53 PM UTC-2, Bart wrote:
> >> Interesting article here on converting large projects into just a few
> >> source files:
> >>
> >> https://blog.forrestthewoods.com/improving-open-source-with-amalgamation-cf293592c5f4#.jzgq6ppvn
> 
> > Hi, I like the concept of one-unit of compilation.
> > (I also have implemented an C preprocessor.)
> 
> (I'm the middle of one at the minute. Most online refs on writing 
> compilers tend to ignore this piffling little obstacle that you have to 
> overcome first!)

I didn't find a good references. I did it completely wrong at the beginning.
This is an sample from C standard that shows me my first mistakes.

#define hash_hash # ## #
#define mkstr(a) # a
#define in_between(a) mkstr(a)
#define join(c, d) in_between(c hash_hash d)
char p[] = join(x, y);
// equivalent to
// char p[] = "x ## y";

I saw much more mistakes, parsing real code. (windows.h)
It also requires expression evaluation for #if with the operator defined etc.

[...]


> OS where the right modules have to be picked). I'll be glad when my new 
> C to C translator works then it'll be automatic.

What is this "C to C translator"? 

I guess C Front, had these problems at the beginning when it use to generate C code.
C++ headers (class declaration) have different representation in C.
I think one possible solution could be generate an include with different declarations.

for instance:

--file1.h
class X { int i; };

--file1.cpp
#include "file1.h"

So to generate C:

--file1_modified.h

struct X { int i; };

--file1.c
#include "file1_modified.h"


The include still there but replaces by file1_modified.h
If the generated file is not for humans then the code could be all expanded with no includes.
But I think if the generated code looks natural then the adoption 
of some tool would be better because the programmers could take ownership of the code if they didn't like the tool.
This is another problem, how to keep macros at the generated code instead of expand it all.



> I wonder why other open source products don't take the same approach? 
> Sometimes people just aren't interested in the details of how a project 
> is structured, they just want to compile whatever source code is needed 
> and end up with an executable, without any fuss, or having to install 
> half of Unix.

I know more two projects using just one unit of compilation. One looks "merged" and the other manually created with in one file.

http://duktape.org/guide.html

[toc] | [prev] | [next] | [standalone]


#101040

FromBartC <bc@freeuk.com>
Date2017-01-03 21:36 +0000
Message-ID<o4h5ei$1ht$1@dont-email.me>
In reply to#101032
On 03/01/2017 20:48, Thiago Adams wrote:
> On Tuesday, January 3, 2017 at 5:47:24 PM UTC-2, Bart wrote:
>> On 03/01/2017 16:47, Thiago Adams wrote:

>>> (I also have implemented an C preprocessor.)
>>
>> (I'm [in] the middle of one at the minute. Most online refs on writing
>> compilers tend to ignore this piffling little obstacle that you have to
>> overcome first!)
>
> I didn't find a good references. I did it completely wrong at the beginning.
> This is an sample from C standard that shows me my first mistakes.
>
> #define hash_hash # ## #
> #define mkstr(a) # a
> #define in_between(a) mkstr(a)
> #define join(c, d) in_between(c hash_hash d)
> char p[] = join(x, y);
> // equivalent to
> // char p[] = "x ## y";
>
> I saw much more mistakes, parsing real code. (windows.h)

I'll have to make a collection of tricky examples for my testing.

(But I've just seen one detail I hadn't allowed for, in gcc.c (from 
http://people.csail.mit.edu/smcc/projects/single-file-programs/). On 
line 733881 in a macro call:

DEF_FORMAT_ATTRIBUTE(PRINTF,1,1_0)

The token '1_0' appears. It starts as a number but presumably must be 
treated as alphanumeric.

I don't know if that puts paid to the idea of introducing underscores as 
numeric separators; from the bizarreness of how the CPP works, probably 
not!)

>> OS where the right modules have to be picked). I'll be glad when my new
>> C to C translator works then it'll be automatic.
>
> What is this "C to C translator"?

It was originally a compiler for another language with C source as a 
possible target (which builds entire projects). Then I thought it would 
be more fun to work on a front end for C source.

But retaining a C output option has several benefits, including 
converting multi-module apps to single-file C source code, and 
translating experimental language extensions to standard C.

> I guess C Front, had these problems at the beginning when it use to generate C code.
> C++ headers (class declaration) have different representation in C.
> I think one possible solution could be generate an include with different declarations.

C must be able to directly implement what is being expressed in the 
source language. I've had to drop (or avoid using) some features because 
of that restriction.

-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#101058

FromThiago Adams <thiago.adams@gmail.com>
Date2017-01-03 16:01 -0800
Message-ID<f7b25ec4-e790-4ddd-acef-39a438c3b2af@googlegroups.com>
In reply to#101040
On Tuesday, January 3, 2017 at 7:36:53 PM UTC-2, Bart wrote:
> On 03/01/2017 20:48, Thiago Adams wrote:
> > On Tuesday, January 3, 2017 at 5:47:24 PM UTC-2, Bart wrote:
> >> On 03/01/2017 16:47, Thiago Adams wrote:
> 
> >>> (I also have implemented an C preprocessor.)
> >>
> >> (I'm [in] the middle of one at the minute. Most online refs on writing
> >> compilers tend to ignore this piffling little obstacle that you have to
> >> overcome first!)
> >
> > I didn't find a good references. I did it completely wrong at the beginning.
> > This is an sample from C standard that shows me my first mistakes.
> >
> > #define hash_hash # ## #
> > #define mkstr(a) # a
> > #define in_between(a) mkstr(a)
> > #define join(c, d) in_between(c hash_hash d)
> > char p[] = join(x, y);
> > // equivalent to
> > // char p[] = "x ## y";
> >
> > I saw much more mistakes, parsing real code. (windows.h)
> 
> I'll have to make a collection of tricky examples for my testing.
> 
> (But I've just seen one detail I hadn't allowed for, in gcc.c (from 
> http://people.csail.mit.edu/smcc/projects/single-file-programs/). On 
> line 733881 in a macro call:
> 
> DEF_FORMAT_ATTRIBUTE(PRINTF,1,1_0)
> 
> The token '1_0' appears. It starts as a number but presumably must be 
> treated as alphanumeric.

This did not work for me as well.

#define M(1_0)

M(1)

I have used the same tokens for preprocessor and parser. I just treat they differently.
I think my tokenizer will output [1:number] and [_0:identifier]. I guess my problem is simple i just count the wrong number of arguments for M. I will try to fix later.

 
> I don't know if that puts paid to the idea of introducing underscores as 
> numeric separators; from the bizarreness of how the CPP works, probably 
> not!)
> 
> >> OS where the right modules have to be picked). I'll be glad when my new
> >> C to C translator works then it'll be automatic.
> >
> > What is this "C to C translator"?
> 
> It was originally a compiler for another language with C source as a 
> possible target (which builds entire projects). Then I thought it would 
> be more fun to work on a front end for C source.
> 
> But retaining a C output option has several benefits, including 
> converting multi-module apps to single-file C source code, and 
> translating experimental language extensions to standard C.

If you do language extensions for instance I think the users would like to see one "natural" code.
This is almost like a code format, where you must keep comments and macro without expansion. 
For instance, if the programmer use #ifdef then the code extension should be always processed for each #ifdef option. If the generated C code were "natural" it could include these #ifdefs. Also for debbuging. And instead of having one big file you could keep the same file logic that user choose. As an option the compiler could generate the module one-file only. 

Today I can read one translation unit and generate the AST.  After that I can generate C code again.
If I do that, the generated code will contain all the definitions from system includes for instance, and no macros.
For each declaration I have the source file, so I can ignore declaration from extern code. Doing this the generated code is small but all the macros and #ifs disappears  (expanded).

I think I can keep comments inside the AST as something appended on each ast node.

for macros I dont have idea what to do.

[toc] | [prev] | [next] | [standalone]


#101063

FromKeith Thompson <kst-u@mib.org>
Date2017-01-03 16:26 -0800
Message-ID<ln7f6bu0ud.fsf@kst-u.example.com>
In reply to#101058
Thiago Adams <thiago.adams@gmail.com> writes:
> On Tuesday, January 3, 2017 at 7:36:53 PM UTC-2, Bart wrote:
[...]
>> (But I've just seen one detail I hadn't allowed for, in gcc.c (from 
>> http://people.csail.mit.edu/smcc/projects/single-file-programs/). On 
>> line 733881 in a macro call:
>> 
>> DEF_FORMAT_ATTRIBUTE(PRINTF,1,1_0)
>> 
>> The token '1_0' appears. It starts as a number but presumably must be 
>> treated as alphanumeric.

1_0 is a pp-number, which will result in a syntax error if it survives
preprocessing (assuming you're trying to implement ISO C requirements).

> This did not work for me as well.
>
> #define M(1_0)
>
> M(1)

What did you expect that to do?  If the macro name in a #define is
followed by a '(' with no whitespace, the '( is followed by a list of
macro parameter names, which must be identifiers.  1_0 is not valid in
that context.  "gcc -E" complains:

    error: "1_0" may not appear in macro parameter list

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#101074

FromThiago Adams <thiago.adams@gmail.com>
Date2017-01-03 18:00 -0800
Message-ID<ec9255fd-e01d-457f-b1e4-73004206bdf0@googlegroups.com>
In reply to#101063
On Tuesday, January 3, 2017 at 10:25:20 PM UTC-2, Keith Thompson wrote:
> Thiago Adams  writes:
> > On Tuesday, January 3, 2017 at 7:36:53 PM UTC-2, Bart wrote:
> [...]
> >> (But I've just seen one detail I hadn't allowed for, in gcc.c (from 
> >> http://people.csail.mit.edu/smcc/projects/single-file-programs/). On 
> >> line 733881 in a macro call:
> >> 
> >> DEF_FORMAT_ATTRIBUTE(PRINTF,1,1_0)
> >> 
> >> The token '1_0' appears. It starts as a number but presumably must be 
> >> treated as alphanumeric.
> 
> 1_0 is a pp-number, which will result in a syntax error if it survives
> preprocessing (assuming you're trying to implement ISO C requirements).
> 
> > This did not work for me as well.
> >
> > #define M(1_0)
> >
> > M(1)
> 
> What did you expect that to do?  If the macro name in a #define is
> followed by a '(' with no whitespace, the '( is followed by a list of
> macro parameter names, which must be identifiers.  1_0 is not valid in
> that context.  "gcc -E" complains:
> 
>     error: "1_0" may not appear in macro parameter list

I have done an wrong sample: 
So the previous one , I just need to emit a
better error message. (I got an assert)

Let's try again:

#define M(a) X##a

M(1_0)

my preprocessor output is:

X1 _0 

the VC preprocessor output is :

X1_0

So my preprocessor still wrong.
Before to expand M , the argument 1_0 is expanded to 1 _0.
I insert spaces.


[toc] | [prev] | [next] | [standalone]


#101076

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-01-04 03:34 +0000
Message-ID<87fukzfqgf.fsf@bsb.me.uk>
In reply to#101074
Thiago Adams <thiago.adams@gmail.com> writes:
<snip>
> Let's try again:
>
> #define M(a) X##a
>
> M(1_0)
>
> my preprocessor output is:
>
> X1 _0 
>
> the VC preprocessor output is :
>
> X1_0
>
> So my preprocessor still wrong.
> Before to expand M , the argument 1_0 is expanded to 1 _0.
> I insert spaces.

Yes, because you are treating 1_0 as two tokens.  You are doing this
because you've not followed the syntax for pp-token in the standard.
1_0 is a single token: a pp-number.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#101085

FromThiago Adams <thiago.adams@gmail.com>
Date2017-01-04 03:31 -0800
Message-ID<46198357-d432-4b81-af4a-0f854ad0f996@googlegroups.com>
In reply to#101076
On Wednesday, January 4, 2017 at 1:34:51 AM UTC-2, Ben Bacarisse wrote:
> Thiago Adams  writes:
> <snip>
> > Let's try again:
> >
> > #define M(a) X##a
> >
> > M(1_0)
> >
> > my preprocessor output is:
> >
> > X1 _0 
> >
> > the VC preprocessor output is :
> >
> > X1_0
> >
> > So my preprocessor still wrong.
> > Before to expand M , the argument 1_0 is expanded to 1 _0.
> > I insert spaces.
> 
> Yes, because you are treating 1_0 as two tokens.  You are doing this
> because you've not followed the syntax for pp-token in the standard.
> 1_0 is a single token: a pp-number.
> 

Thanks.
I didn't see pp-number correctly yesterday.
Creating this single token it will work.

-
I am still adding extra spaces between tokens (except for ##)


#define M(a) a

M(   +++++   )

My preprocessor
++ ++ + 

VC preprocessor

+++++

But I think this will not create problems except more 
text to see.

[toc] | [prev] | [next] | [standalone]


#101087

FromBartC <bc@freeuk.com>
Date2017-01-04 12:03 +0000
Message-ID<o4io7d$c95$1@dont-email.me>
In reply to#101085
On 04/01/2017 11:31, Thiago Adams wrote:

> I am still adding extra spaces between tokens (except for ##)
>
>
> #define M(a) a
>
> M(   +++++   )
>
> My preprocessor
> ++ ++ +
>
> VC preprocessor
>
> +++++
>
> But I think this will not create problems except more
> text to see.

What happens when you stringify the result? Eg:

#define M2(x) #x

M2(M(   +++++   ))



-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#101089

FromThiago Adams <thiago.adams@gmail.com>
Date2017-01-04 05:00 -0800
Message-ID<c901fe2c-600f-430c-be7c-3bfc274e06e3@googlegroups.com>
In reply to#101087
On Wednesday, January 4, 2017 at 10:03:30 AM UTC-2, Bart wrote:
> On 04/01/2017 11:31, Thiago Adams wrote:
> 
> > I am still adding extra spaces between tokens (except for ##)
> >
> >
> > #define M(a) a
> >
> > M(   +++++   )
> >
> > My preprocessor
> > ++ ++ +
> >
> > VC preprocessor
> >
> > +++++
> >
> > But I think this will not create problems except more
> > text to see.
> 
> What happens when you stringify the result? Eg:
> 
> #define M2(x) #x
> 
> M2(M(   +++++   ))
> 
> 
> 

#define M(a) a 
#define M2(x) #x 

M2(M(     +++++    ))

Visual C++ preprocessor and clang: (just one space added)

"M( +++++ )"

My preprocessor:
(I also need a unit test for this)

"++ ++ +" 

This was unexpected to me. 
Well, my preprocessor has a lot of errors. 
After to parser window.h I didn't check anymore if 
my preprocessor was right and just move to the parser.

I can try to create a github project with only the preprocessor.
Some parts of the parser are used also, because to evaluate #if expression I am using the same 'const-expression'  used in 
parser.

[toc] | [prev] | [next] | [standalone]


#101159

FromThiago Adams <thiago.adams@gmail.com>
Date2017-01-05 02:38 -0800
Message-ID<8b7b2773-2a60-44c5-a9f4-e5fa23eff966@googlegroups.com>
In reply to#101089
On Wednesday, January 4, 2017 at 11:00:30 AM UTC-2, Thiago Adams wrote:
> On Wednesday, January 4, 2017 at 10:03:30 AM UTC-2, Bart wrote:
> > On 04/01/2017 11:31, Thiago Adams wrote:
> > 
> > > I am still adding extra spaces between tokens (except for ##)
> > >
> > >
> > > #define M(a) a
> > >
> > > M(   +++++   )
> > >
> > > My preprocessor
> > > ++ ++ +
> > >
> > > VC preprocessor
> > >
> > > +++++
> > >
> > > But I think this will not create problems except more
> > > text to see.
> > 
> > What happens when you stringify the result? Eg:
> > 
> > #define M2(x) #x
> > 
> > M2(M(   +++++   ))
> > 
> > 
> > 
> 
> #define M(a) a 
> #define M2(x) #x 
> 
> M2(M(     +++++    ))
> 
> Visual C++ preprocessor and clang: (just one space added)
> 
> "M( +++++ )"
> 
> My preprocessor:
> (I also need a unit test for this)
> 
> "++ ++ +" 
> 
> This was unexpected to me. 

I did one more sample to see what happens:

#define M(a) X##a
#define M2(a, b) #a a b

M2(  M ( 1), M(1))

VC++ preprocessor output:

"M ( 1)" X1 X1

The same argument 'a' for macro can or not be expanded before 
the macro invocation.

Today I keep a map "parameter-name:a" - > "expanded:X1"

To fix my preprocessor I will keep both:

  "parameter-name:a" - > ["expanded:X1", "not expanded:M ( 1)"] 

and use the appropriated value depending on #a or a.

I will do the expansion (X1) before the macro call, I am 
not sure if is correct.


[toc] | [prev] | [next] | [standalone]


#101172

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-01-05 14:28 +0000
Message-ID<87bmvlk2cr.fsf@bsb.me.uk>
In reply to#101159
Thiago Adams <thiago.adams@gmail.com> writes:
<snip>
> I did one more sample to see what happens:
>
> #define M(a) X##a
> #define M2(a, b) #a a b
>
> M2(  M ( 1), M(1))
>
> VC++ preprocessor output:
>
> "M ( 1)" X1 X1
>
> The same argument 'a' for macro can or not be expanded before 
> the macro invocation.
>
> Today I keep a map "parameter-name:a" - > "expanded:X1"
>
> To fix my preprocessor I will keep both:
>
>   "parameter-name:a" - > ["expanded:X1", "not expanded:M ( 1)"] 
>
> and use the appropriated value depending on #a or a.

That seems like a very odd way to do it.  Have you read what the C
standard says about macro expansion?  It explains the algorithm quite
well, in my option.  If you expand macros at the right time, you won't
need to keep both expanded and un-expanded versions.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#101177

Fromsupercat@casperkitty.com
Date2017-01-05 08:20 -0800
Message-ID<a7f547cf-ab84-4610-9607-ae4eaec7b152@googlegroups.com>
In reply to#101172
On Thursday, January 5, 2017 at 8:28:46 AM UTC-6, Ben Bacarisse wrote:
> That seems like a very odd way to do it.  Have you read what the C
> standard says about macro expansion?  It explains the algorithm quite
> well, in my option.  If you expand macros at the right time, you won't
> need to keep both expanded and un-expanded versions.

Given something like:

    #define join(a,b) a##b
    #define join2(a,b) join(a,b)
    #define plus() +
    #define incplusinc join2(+,plus()plus()++)
    #define incplusplusplus join2(+,plus()plus()plus()plus())

    #define asString2(x) #x
    #define asString(x) asString2(x)

    void useString(char const *st);
    void useInt(int x);
    volatile int xx,yy;
    void test(void)
    {
      useInt(xx incplusinc  yy);
      useString("#1:" asString(incplusinc));
      useInt(xx incplusplusplus yy);
      useString("#2:" asString(incplusplusplus));
    }

How could a compiler avoid having to either use different expansion logic
in cases where a macro is used as an operand to # versus cases where it
isn't, use some special delimiter for token boundaries that will evaporate
when string-expanded, or have the macro expansion logic produce two forms
of expanded macro based upon the intended usage?

Both incplusinc and incplusplusplus expand to the literal character sequence
+++++, but the first groups the tokens as ++ + ++ and the second as ++ + + +.
The plus() macro used on the right hand side of the token-pasting operator
must be expanded to + before the token-pasting operator is applied, and it
would seem that the other uses of plus() to the right of that operator would
get expanded at the same time.

What would you suggest as the process by which a compiler should handle the
above code?

[toc] | [prev] | [next] | [standalone]


#101181

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-01-05 17:05 +0000
Message-ID<871swhjv3q.fsf@bsb.me.uk>
In reply to#101177
supercat@casperkitty.com writes:
<snip>
> How could a compiler avoid having to either use different expansion logic
> in cases where a macro is used as an operand to # versus cases where it
> isn't,

The pre-processor should follow the specified algorithm.  The fact that
you refer to "a macro" bring an operand to # suggests you haven't
studied that algorithm.  The operand of # is a parameter name and the
corresponding argument sequence (a list of token) is never expanded
before being turned into a string.

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#101190

Fromsupercat@casperkitty.com
Date2017-01-05 10:11 -0800
Message-ID<2f8a7a13-ba5a-46da-b9a5-eb84223d00a7@googlegroups.com>
In reply to#101181
On Thursday, January 5, 2017 at 11:05:23 AM UTC-6, Ben Bacarisse wrote:
> supercat writes:
> <snip>
> > How could a compiler avoid having to either use different expansion logic
> > in cases where a macro is used as an operand to # versus cases where it
> > isn't,
> 
> The pre-processor should follow the specified algorithm.  The fact that
> you refer to "a macro" bring an operand to # suggests you haven't
> studied that algorithm.  The operand of # is a parameter name and the
> corresponding argument sequence (a list of token) is never expanded
> before being turned into a string.

Within the asString2 macro (the one that uses #), it acts upon the named
parameter x, but the purpose of that macro is to apply the operator to
the argument; the example code uses that macro twice, and in each case it
is applied to the expansion of another macro.  The expansions of both of
the macros to which it is applied have identical string representations
(i.e. +++++) but one behaves like ++ + ++ and the other behaves like
++ + + +.  Given the difference between the string representation that
would be needed for #, and the way in which the tokens would need to be
output for downstream processing, I would think keeping track of string
representations with and without the added spaces would be a reasonable
way to handle that (to get the string representation of two tokens that
appear without whitespace or are explicitly pasted, simply concatenate
their string representations; for the semantic form, either concatenate
the semantic forms with a whitespace between them (for consecutive
placement without a pasting operator) or with any whitespace between
them suppressed (when using the ## pasting operator).

While keeping track of both string forms would hardly be the only way to
handle things, it doesn't seem like an unreasonable one.  An alternative
would be to define an "invisible whitespace" character which will not get
included in strings generated by the # operator, but will get replaced
with whitespace in unquoted preprocessor output.

[toc] | [prev] | [next] | [standalone]


#101197

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-01-05 19:46 +0000
Message-ID<87eg0hi92q.fsf@bsb.me.uk>
In reply to#101190
supercat@casperkitty.com writes:

> On Thursday, January 5, 2017 at 11:05:23 AM UTC-6, Ben Bacarisse wrote:
>> supercat writes:
>> <snip>
>> > How could a compiler avoid having to either use different expansion logic
>> > in cases where a macro is used as an operand to # versus cases where it
>> > isn't,
>> 
>> The pre-processor should follow the specified algorithm.  The fact that
>> you refer to "a macro" bring an operand to # suggests you haven't
>> studied that algorithm.  The operand of # is a parameter name and the
>> corresponding argument sequence (a list of token) is never expanded
>> before being turned into a string.
>
> Within the asString2 macro (the one that uses #), it acts upon the named
> parameter x, but the purpose of that macro is to apply the operator to
> the argument; the example code uses that macro twice, and in each case it
> is applied to the expansion of another macro.  The expansions of both of
> the macros to which it is applied have identical string representations
> (i.e. +++++) but one behaves like ++ + ++ and the other behaves like
> ++ + + +.  Given the difference between the string representation that
> would be needed for #, and the way in which the tokens would need to be
> output for downstream processing, I would think keeping track of string
> representations with and without the added spaces would be a reasonable
> way to handle that

I wouldn't.  I think it's much simpler to process token lists.  But I
haven't implemented it both way so I can't be 100% sure.  If your
intuition suggests multiple string representations are going to be a
good method, I can't talk you out of it, but my intuition (and
experience of having done it the other way) are saying that it's
bordering on bonkers.

Unfortunately it's too large a task to do just for the hell of finding
out, so let's agree to differ.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#101200

FromThiago Adams <thiago.adams@gmail.com>
Date2017-01-05 12:15 -0800
Message-ID<2caaa38b-49f5-499d-b748-9dd9ec7abe0d@googlegroups.com>
In reply to#101197
On Thursday, January 5, 2017 at 5:46:28 PM UTC-2, Ben Bacarisse wrote:
>  writes:
> 
> > On Thursday, January 5, 2017 at 11:05:23 AM UTC-6, Ben Bacarisse wrote:
> >> supercat writes:
> >> <snip>
> >> > How could a compiler avoid having to either use different expansion logic
> >> > in cases where a macro is used as an operand to # versus cases where it
> >> > isn't,
> >> 
> >> The pre-processor should follow the specified algorithm.  The fact that
> >> you refer to "a macro" bring an operand to # suggests you haven't
> >> studied that algorithm.  The operand of # is a parameter name and the
> >> corresponding argument sequence (a list of token) is never expanded
> >> before being turned into a string.
> >
> > Within the asString2 macro (the one that uses #), it acts upon the named
> > parameter x, but the purpose of that macro is to apply the operator to
> > the argument; the example code uses that macro twice, and in each case it
> > is applied to the expansion of another macro.  The expansions of both of
> > the macros to which it is applied have identical string representations
> > (i.e. +++++) but one behaves like ++ + ++ and the other behaves like
> > ++ + + +.  Given the difference between the string representation that
> > would be needed for #, and the way in which the tokens would need to be
> > output for downstream processing, I would think keeping track of string
> > representations with and without the added spaces would be a reasonable
> > way to handle that
> 
> I wouldn't.  I think it's much simpler to process token lists.  But I
> haven't implemented it both way so I can't be 100% sure.  If your
> intuition suggests multiple string representations are going to be a
> good method, I can't talk you out of it, but my intuition (and
> experience of having done it the other way) are saying that it's
> bordering on bonkers.
> 
> Unfortunately it's too large a task to do just for the hell of finding
> out, so let's agree to differ.
> 

My design for this preprocessor was to create an 
scanner where I could pull tokens already pre-processed.
I didn't want to preprocessor all files and generate 
temporaries before parsing. The dirty job must be done by
this "scanner" component.


To implement #idef #else for instance,
I had to create internal states because it's not using 
recursive functions. I have a stack for includes and 
macros being expanded. 

My idea to keep the "not-expand-string"  was to save the 
expansion code I have so far. But It can be completed replaced
by a new one and keep the other parts of my scanner.
That project I put on git is useful for that.

[toc] | [prev] | [next] | [standalone]


#101206

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-01-05 21:54 +0000
Message-ID<87tw9dgokf.fsf@bsb.me.uk>
In reply to#101200
Thiago Adams <thiago.adams@gmail.com> writes:
<snip>
> My idea to keep the "not-expand-string"  was to save the 
> expansion code I have so far. But It can be completed replaced
> by a new one and keep the other parts of my scanner.
> That project I put on git is useful for that.

Sorry, I could not really follow this but it seems we may be talking
about different things.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


Page 1 of 3  [1] 2 3  Next page →

Back to top | Article view | comp.lang.c


csiph-web