lf-lang / lingua-franca

Intuitive concurrent programming in any language
https://www.lf-lang.org
Other
224 stars 60 forks source link

LF Code doesn't compile if filename has hyphen (-) #2187

Open mkhubaibumer opened 6 months ago

mkhubaibumer commented 6 months ago

If LF source file is named with a hyphen(-) in the name, code compilation fails

target C;

reactor A {
    timer t(0, 2sec)
    reaction(t) {=
        printf("hello\n");
    =}
}

main reactor {
    a = new A();
}

save this snippet as a-1.lf

Running this produces

Cleaning /Users/khubaibumer/aws_work/include
--- Current working directory: /Users/khubaibumer/aws_work/src-gen/a-1/build
--- Executing command: cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/Users/khubaibumer/aws_work -DCMAKE_INSTALL_BINDIR=bin -DLF_FILE_SEPARATOR="/" -DLF_SOURCE_DIRECTORY="/Users/khubaibumer/aws_work/src" -DLF_PACKAGE_DIRECTORY="/Users/khubaibumer/aws_work" /Users/khubaibumer/aws_work/src-gen/a-1
-- The C compiler identification is AppleClang 15.0.0.15000100
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Including sources for threaded runtime with 0 worker(s) with scheduler=SCHED_NP and tracing=.
-- Including the following sources: tag.c, port.c, mixed_radix.c, reactor_common.c, lf_token.c, environment.c, reactor_threaded.c, scheduler_adaptive.c, scheduler_GEDF_NP.c, scheduler_NP.c, scheduler_sync_tag_advance.c, scheduler_instance.c, watchdog.c, vector.c, pqueue_base.c, pqueue_tag.c, pqueue.c, util.c, semaphore.c, hashset.c, hashset_itr.c, modes.c, lf_unix_clock_support.c, lf_unix_syscall_support.c, lf_linux_support.c, lf_macos_support.c, lf_windows_support.c, lf_nrf52_support.c, lf_zephyr_support.c, lf_zephyr_clock_counter.c, lf_zephyr_clock_kernel.c, lf_rp2040_support.c
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
-- Found Threads: TRUE  
-- Applying preprocessor definitions...
-- LF_REACTION_GRAPH_BREADTH=1
-- LOG_LEVEL=2
-- NUMBER_OF_WORKERS=0
-- SCHEDULER=SCHED_NP
-- LF_SOURCE_DIRECTORY="/Users/khubaibumer/aws_work/src"
-- LF_PACKAGE_DIRECTORY="/Users/khubaibumer/aws_work"
-- LF_FILE_SEPARATOR="/"
-- Configuring done (1.2s)
-- Generating done (0.1s)
-- Build files have been written to: /Users/khubaibumer/aws_work/src-gen/a-1/build
--- Current working directory: /Users/khubaibumer/aws_work/src-gen/a-1/build
--- Executing command: cmake --build . --target install --parallel 8 --config Debug
[  2%] Building C object core/CMakeFiles/core.dir/tag.c.o
[  5%] Building C object core/CMakeFiles/core.dir/port.c.o
[  7%] Building C object core/CMakeFiles/core.dir/lf_token.c.o
[ 10%] Building C object core/CMakeFiles/core.dir/mixed_radix.c.o
[ 13%] Building C object core/CMakeFiles/core.dir/threaded/reactor_threaded.c.o
[ 15%] Building C object core/CMakeFiles/core.dir/environment.c.o
[ 18%] Building C object core/CMakeFiles/core.dir/reactor_common.c.o
[ 21%] Building C object core/CMakeFiles/core.dir/threaded/scheduler_adaptive.c.o
[ 23%] Building C object core/CMakeFiles/core.dir/threaded/scheduler_GEDF_NP.c.o
[ 26%] Building C object core/CMakeFiles/core.dir/threaded/scheduler_NP.c.o
[ 28%] Building C object core/CMakeFiles/core.dir/threaded/scheduler_instance.c.o
[ 31%] Building C object core/CMakeFiles/core.dir/threaded/scheduler_sync_tag_advance.c.o
[ 34%] Building C object core/CMakeFiles/core.dir/threaded/watchdog.c.o
[ 36%] Building C object core/CMakeFiles/core.dir/utils/vector.c.o
[ 39%] Building C object core/CMakeFiles/core.dir/utils/pqueue_base.c.o
[ 42%] Building C object core/CMakeFiles/core.dir/utils/pqueue_tag.c.o
[ 44%] Building C object core/CMakeFiles/core.dir/utils/pqueue.c.o
[ 47%] Building C object core/CMakeFiles/core.dir/utils/util.c.o
[ 50%] Building C object core/CMakeFiles/core.dir/utils/hashset/hashset.c.o
[ 52%] Building C object core/CMakeFiles/core.dir/utils/semaphore.c.o
[ 55%] Building C object core/CMakeFiles/core.dir/utils/hashset/hashset_itr.c.o
[ 57%] Building C object core/CMakeFiles/core.dir/modal_models/modes.c.o
[ 60%] Building C object core/CMakeFiles/core.dir/platform/lf_unix_clock_support.c.o
[ 63%] Building C object core/CMakeFiles/core.dir/platform/lf_unix_syscall_support.c.o
[ 65%] Building C object core/CMakeFiles/core.dir/platform/lf_linux_support.c.o
[ 68%] Building C object core/CMakeFiles/core.dir/platform/lf_macos_support.c.o
[ 71%] Building C object core/CMakeFiles/core.dir/platform/lf_windows_support.c.o
[ 73%] Building C object core/CMakeFiles/core.dir/platform/lf_nrf52_support.c.o
[ 76%] Building C object core/CMakeFiles/core.dir/platform/lf_zephyr_support.c.o
[ 78%] Building C object core/CMakeFiles/core.dir/platform/lf_zephyr_clock_counter.c.o
[ 81%] Building C object core/CMakeFiles/core.dir/platform/lf_zephyr_clock_kernel.c.o
[ 84%] Building C object core/CMakeFiles/core.dir/platform/lf_rp2040_support.c.o
[ 86%] Linking C static library libcore.a
[ 86%] Built target core
[ 89%] Building C object CMakeFiles/a-1.dir/_a.c.o
[ 92%] Building C object CMakeFiles/a-1.dir/a-1.c.o
[ 94%] Building C object CMakeFiles/a-1.dir/lib/schedule.c.o
[ 97%] Building C object CMakeFiles/a-1.dir/_a-1_main.c.o
In file included from /Users/khubaibumer/aws_work/src-gen/a-1/_a-1_main.c:3:
/Users/khubaibumer/aws_work/src-gen/a-1/./include/a-1/a-1.h:1:11: warning: extra tokens at end of #ifndef directive [-Wextra-tokens]
#ifndef _a-1_main_H
          ^
          //
/Users/khubaibumer/aws_work/src-gen/a-1/./include/a-1/a-1.h:2:11: warning: ISO C99 requires whitespace after the macro name [-Wc99-extensions]
#define _a-1_main_H
          ^
/Users/khubaibumer/aws_work/src-gen/a-1/./include/a-1/a-1.h:3:11: warning: extra tokens at end of #ifndef directive [-Wextra-tokens]
#ifndef _A-1_MAIN_H // necessary for arduino-cli, which automatically includes headers that are not used
          ^
          //
In file included from /Users/khubaibumer/aws_work/src-gen/a-1/a-1.c:21:
/Users/khubaibumer/aws_work/src-gen/a-1/./_a-1_main.h:1:11: warning: extra tokens at end of #ifndef directive [-Wextra-tokens]
#ifndef _A-1_MAIN_H
          ^
          //
/Users/khubaibumer/aws_work/src-gen/a-1/./_a-1_main.h:2:11: warning: ISO C99 requires whitespace after the macro name [-Wc99-extensions]
#define _A-1_MAIN_H
          ^
/Users/khubaibumer/aws_work/src-gen/a-1/_a-1_main.h:12:5: error: expected ';' after top level declarator
} _a-1_main_main_self_t;
    ^
    ;
/Users/khubaibumer/aws_work/src-gen/a-1/_a-1_main.h:13:3: error: expected identifier or '('
_a-1_main_main_self_t* new__a-1_main();
  ^
/Users/khubaibumer/aws_work/src-gen/a-1/./include/a-1/a-1.h:15:17: error: expected identifier or '('
typedef struct a-1_self_t{
                ^
/Users/khubaibumer/aws_work/src-gen/a-1/./include/a-1/a-1.h:18:3: error: must use 'struct' tag to refer to type 'a'
} a-1_self_t;
  ^
  struct 
/Users/khubaibumer/aws_work/src-gen/a-1/./include/a-1/a-1.h:18:4: error: expected identifier or '('
/Users/khubaibumer/aws_work/src-gen/a-1/a-1.c:53:7: error: expected identifier or '('
    _a-1_main_main_self_t* a_1_main_self[1];
      ^
} a-1_self_t;
   ^
In file included from /Users/khubaibumer/aws_work/src-gen/a-1/_a-1_main.c:4:
/Users/khubaibumer/aws_work/src-gen/a-1/./_a-1_main.h:1:11: warning: extra tokens at end of #ifndef directive [-Wextra-tokens]
#ifndef _A-1_MAIN_H
          ^
          //
/Users/khubaibumer/aws_work/src-gen/a-1/./_a-1_main.h:2:11: warning: ISO C99 requires whitespace after the macro name [-Wc99-extensions]
#define _A-1_MAIN_H
          ^
/Users/khubaibumer/aws_work/src-gen/a-1/_a-1_main.h:12:2: error: expected ';' after struct
} _a-1_main_main_self_t;
 ^
 ;
/Users/khubaibumer/aws_work/src-gen/a-1/./_a-1_main.h:8:1: warning: typedef requires a name [-Wmissing-declarations]
typedef struct {
^~~~~~~
/Users/khubaibumer/aws_work/src-gen/a-1/_a-1_main.h:12:3: error: expected external declaration
} _a-1_main_main_self_t;
  ^
/Users/khubaibumer/aws_work/src-gen/a-1/./include/a-1/a-1.h:2:11: note: expanded from macro '_a'
#define _a-1_main_H
          ^
In file included from /Users/khubaibumer/aws_work/src-gen/a-1/_a-1_main.c:4:
/Users/khubaibumer/aws_work/src-gen/a-1/_a-1_main.h:12:3: error: expected identifier or '('
/Users/khubaibumer/aws_work/src-gen/a-1/./include/a-1/a-1.h:2:12: note: expanded from macro '_a'
#define _a-1_main_H
           ^
In file included from /Users/khubaibumer/aws_work/src-gen/a-1/_a-1_main.c:4:
/Users/khubaibumer/aws_work/src-gen/a-1/_a-1_main.h:13:1: error: expected external declaration
_a-1_main_main_self_t* new__a-1_main();
^
/Users/khubaibumer/aws_work/src-gen/a-1/./include/a-1/a-1.h:2:11: note: expanded from macro '_a'
#define _a-1_main_H
          ^
In file included from /Users/khubaibumer/aws_work/src-gen/a-1/_a-1_main.c:4:
/Users/khubaibumer/aws_work/src-gen/a-1/_a-1_main.h:13:1: error: expected identifier or '('
/Users/khubaibumer/aws_work/src-gen/a-1/a-1.c/Users/khubaibumer/aws_work/src-gen/a-1/./include/a-1/a-1.h:2:12: note: expanded from macro '_a'
:#define _a-1_main_H54:
29           ^
: error: use of undeclared identifier 'a_1_main_self'
/Users/khubaibumer/aws_work/src-gen/a-1/_a-1_main.c:7:1: error: expected external declaration
_a-1_main_main_self_t* new__a-1_main() {
^
/Users/khubaibumer/aws_work/src-gen/a-1/./include/a-1/a-1.h:2:11: note: expanded from macro '_a'
#define _a-1_main_H
          ^
/Users/khubaibumer/aws_work/src-gen/a-1/_a-1_main.c:7:1: error: expected identifier or '('
/Users/khubaibumer/aws_work/src-gen/a-1/./include/a-1/a-1.h:2:12: note: expanded from macro '_a'
#define _a-1_main_H
           ^
    SUPPRESS_UNUSED_WARNING(a_1_main_self);
                            ^
6 warnings and 10 errors generated.
/Users/khubaibumer/aws_work/src-gen/a-1/a-1.c:58:5: error: use of undeclared identifier 'a_1_main_self'; did you mean 'a_1_a_self'?
    a_1_main_self[0] = new__a-1_main();
    ^~~~~~~~~~~~~
    a_1_a_self
/Users/khubaibumer/aws_work/src-gen/a-1/a-1.c:55:16: note: 'a_1_a_self' declared here
    _a_self_t* a_1_a_self[1];
               ^
/Users/khubaibumer/aws_work/src-gen/a-1/a-1.c:58:32: error: invalid suffix '_main' on integer constant
    a_1_main_self[0] = new__a-1_main();
                               ^
/Users/khubaibumer/aws_work/src-gen/a-1/a-1.c:59:5: error: use of undeclared identifier 'a_1_main_self'; did you mean 'a_1_a_self'?
    a_1_main_self[0]->base.environment = &envs[a_1_main];
    ^~~~~~~~~~~~~
    a_1_a_self
/Users/khubaibumer/aws_work/src-gen/a-1/a-1.c:55:16: note: 'a_1_a_self' declared here
    _a_self_t* a_1_a_self[1];
               ^
/Users/khubaibumer/aws_work/src-gen/a-1/a-1.c:64:11: error: expected identifier or '('
        _a-1_main_main_self_t *self = a_1_main_self[0];
          ^
2 warnings and 8 errors generated.
make[2]: *** [CMakeFiles/a-1.dir/_a-1_main.c.o] Error 1
make[2]: *** Waiting for unfinished jobs....
make[2]: *** [CMakeFiles/a-1.dir/a-1.c.o] Error 1
make[1]: *** [CMakeFiles/a-1.dir/all] Error 2
make: *** [all] Error 2
lhstrh commented 4 months ago

This is an issue in the name mangling.

petervdonovan commented 2 months ago

The problem here is that if the file is named a-1, then implicitly that means that the name of the main reactor is a-1, which isn't a valid identifier. For any other reactor, our validator would catch this and forbid naming a reactor class with an invalid identifier, but that isn't what we do here.

As a result, the correct solution to this is non-obvious. I lean toward forbidding the use of file names with hyphens. The alternatives would involve ending the convention that reactor names are valid identifiers or the convention that the name of the main reactor is the file name. Either of these alternatives seem like they could have complicated, potentially backwards-incompatible consequences.

cmnrd commented 2 months ago

Why do we require that the main reactor has the same name as the LF file?

lhstrh commented 2 months ago

Why do we require that the main reactor has the same name as the LF file?

So that when the name is omitted, it is implied by the name of the file.

cmnrd commented 2 months ago

That makes sense if the reactor name is not given. But why do we require that the file name matches the reactor name if it is given? A simple solution to the problem would be to allow the user to specify a main reactor name that differs from the file name.