Core Lucy compiler

Overview

liblucy

liblucy is the core piece of Lucy the DSL. It contains the core compiler that is compiled to wasm for usage in JavaScript environments such as Node.js. It also includes the CLI compiler, lucyc.

Contributing

See the contributing page for information on how to build liblucy and the workflow for making changes.

License

BSD-2-Clause

Comments
  • Typescript Codegen Support

    Typescript Codegen Support

    Opening this issue to spawn a discussion about type-safety. Lucy offers a nice opportunity to increase TS type safety by statically analysing the machine. This is similar to, but much more reliable than, xstate-codegen. xstate-codegen pulls out machines from JS/TS, which is fraught with issues. Lucy could statically analyse files, free of side effects, and create 100% perfect types every time.

    What do perfect types look like?

    1. All actions/guards/services know what events caused them to fire.
    2. state.matches can be made type safe.

    Because Lucy compiles to out.js files, an accompanying .d.ts file would be appropriate. Users could also pass it generics, such as TEvent and TContext, similar to xstate-codegen.

    Interested to hear your thoughts.

    enhancement 
    opened by mattpocock 35
  • Allow for unimplemented actions/services/guards

    Allow for unimplemented actions/services/guards

    Sometimes, actions/services/guards are best implemented not in the initial definition of the machine. Sometimes, it's best to leave them unimplemented until you use the machine in your frontend/backend code.

    This means that Lucy would need to compile action definitions that aren't imported via use.

    enhancement 
    opened by mattpocock 13
  • Error installing on Mac with zsh - command not found: lc

    Error installing on Mac with zsh - command not found: lc

    I'm really interested in trying Lucy! Thanks for your work.

    Problem

    I tried to do what the install page says on my terminal https://lucylang.org/install/:

    curl -sSf https://lucylang.org/install.sh | bash
    

    It went ok!

    Then did

    lc --help
    

    But I get

    zsh: command not found: lc
    

    Checked my .zshrc config and it automatically added a

    export PATH="/Users/santicros/.lucy/bin:$PATH"
    

    Solution

    I found that removing the final $PATH made it work, so:

    export PATH="/Users/santicros/.lucy/bin"
    

    :D

    opened by santicros 5
  • Allow for multiple guards in transitions

    Allow for multiple guards in transitions

    initial state firstState {
      go => guard(isAllowed) => secondState
    }
    
    state secondState {}
    
    state notAllowedState {}
    

    Given a state machine like the one above, how would one default to going to the notAllowedState if isAllowed evaluated to false?

    bug 
    opened by mattpocock 4
  • Invoking

    Invoking "use reference" is incorrectly referenced in services property

    I'm trying to follow the example from Lucy's website for using an "use reference" in invoke statement. I'm quite new to state machines in general so my terminology and expectations might be incorrect here - feel free to correct me.

    Input:

    use './utils' { getUsers }
    
    state idle {
      invoke(:getUsers) {
        done => assign(users)
      }
    }
    

    Output with @lucy/[email protected]:

    01 | import { createMachine, assign } from 'xstate';
    02 | import { getUsers } from './utils';
    03 | 
    04 | export default function({ context = {}, services } = {}) {
    05 |   return createMachine({
    06 |     context,
    07 |     states: {
    08 |       idle: {
    09 |         invoke: {
    10 |           src: 'getUsers',
    11 |           onDone: {
    12 |             actions: [
    13 |               assign({
    14 |                 users: (context, event) => event.data
    15 |               })
    16 |             ]
    17 |           }
    18 |         }
    19 |       }
    20 |     }
    21 |   }, {
    22 |     services: {
    23 |       getUsers: services.getUsers
    24 |     }
    25 |   });
    26 | }
    

    Note that on the line 2 the imported getUsers is an unused variable. It is not used on line 23.

    I would expected the output to be:

    22 |     services: {
    23 |       getUsers,
    24 |     }
    

    or maybe even

    22 |     services: {
    23 |       getUsers,
    24 |       ...services,
    25 |     }
    
    Here is my custom webpack loader which applies a temporary work-around
    module.exports = function(content) {
        const callback = this.async();
    
        import('@lucy/liblucy')
            .then(({ ready, compileXstate }) => {
                ready
                    .then(() => {
                        const { js } = compileXstate(content, this.resourcePath);
    
                        callback(undefined, applyFixes(js));
                    })
                    .catch(e => {
                        callback(
                            `Lucy loader failed to compileXstate: ${e.message}`
                        );
                    });
            })
            .catch(callback);
    };
    
    function applyFixes(input) {
        const output = input.replace(/services\./gi, '');
    
        console.log('input', input);
        console.log('output', output);
    
        return output;
    }
    
    opened by AriPerkkio 2
  • Target a nested state with an event

    Target a nested state with an event

    Given a machine that looks like this:

    initial state idle {
      fetch => fetching
    
      machine idling {
        initial state noError {
          @entry => action(:clearErrorMessage)
        }
    
        state errored {}
      }
    }
    
    state fetching {
      reportError => idle.errored
    }
    

    I would like to target a nested state. Something like reportError => idle.errored.

    bug 
    opened by theianjones 2
  • Add node/browser lib for Lucy

    Add node/browser lib for Lucy

    import { parseToJson } from '@lucylang/node';
    
    const machine = parseToJson(
    `
    // Lucy file in here
    `
    )
    

    Many use-cases for this - JS runtime, browser-based tooling, all sorts of cool stuff.

    opened by mattpocock 2
  • Assign with no transition has `

    Assign with no transition has `"ssign"` or `""` as target

    Hey, Noticed that if you try to make a transition containing only an assign action, it adds a "ssign" target if no other state is defined, or "" if another state is defined (whereas I would expect no target in such a case)

    state initial {
      TEST => assign(someValue)
    }
    

    The resulting code is

    import { createMachine, assign } from 'xstate';
    
    export default createMachine({
      states: {
        initial: {
          on: {
            TEST: {
              target: 'ssign',
              actions: [
                assign({
                  someValue: (context, event) => event.data
                })
              ]
            }
          }
        }
      }
    });
    

    And when doing the following:

    state initial {
      TEST => assign(someValue)
    }
    
    state other {}
    

    The resulting code is

    import { createMachine, assign } from 'xstate';
    
    export default createMachine({
      states: {
        initial: {
          on: {
            TEST: {
              target: '',
              actions: [
                assign({
                  someValue: (context, event) => event.data
                })
              ]
            }
          }
        },
        other: {
    
        }
      }
    });
    

    I'm aware that Lucy is in alpha and issues are to be expected, just wanted to give you a heads up :)

    Good luck!

    bug 
    opened by yoav-lavi 2
  • Not an issue: compilation to Robot and other machine libraries

    Not an issue: compilation to Robot and other machine libraries

    Congrats on the new DSL! It is indeed a significant improvement on the experience of writing large-enough state machines (e.g., using state machines where they do make sense). I have two questions:

    • why not compile to Robot (say, a "strict mode" version of the language that does not include actors)? It still makes sense to have the small size
    • how easy would it be to compile to Kingly -- e.g., another state machine library? Kingly also has a compiler to vanilla JS (zero dependencies) but from a visual language (saved as .graphml file). I am interested to see how this could be used as an equivalent textual language.

    Got to look at your code anyways to see how you did it but thought I'll stop by and ask.

    [edit]: Ok, I had a quick look and it seems like I should be able to reuse your parser. I should just have to rewrite the traversal of the parsed tree (ParseResult). Does that make sense to you? BTW that is terrificly well-written C code. I haven't read C in a decade, and that went like a charm even without comments :-)

    opened by brucou 2
  • Why not javascript?

    Why not javascript?

    Hi there, this project looks great with super exciting potential :D

    I came straight to the github, keen to see juicy implementation details, only to find it written in C, a language that I am generally not good at and find hard to read (and not buildable on windows?) :( Nothing wrong with C of course... I am just curious though, why not typescript / PEGjs for the core? Is javascript really too slow for this?

    opened by thehappycheese 1
  • Guards for immediate transitions

    Guards for immediate transitions

    guard isValid = isValid
    
    initial state firstState {
      => isValid => secondState
    }
    
    state secondState {
    
    }
    

    This appears not to print anything into the cond of the always

    bug 
    opened by mattpocock 1
  • Actions in nested machines

    Actions in nested machines

    I think that i found a bug in lucy 0.3.4

    use './utils.js' {assignDays}
    
    machine testMachine {
      action assignDays = assignDays
    
      initial state test {}
    }
    

    compiles to

    import { createMachine } from 'xstate';
    import { assignDays } from './utils.js';
    
    export function createTestMachine({ context = {} } = {}) {
      return createMachine({
        initial: 'test',
        context,
        states: {
          test: {
    
          }
        }
      }, {
        actions: {
          assignDays: assignDays
        }
      });
    }
    

    which is ok, but

    use './utils.js' {assignDays}
    
    machine testMachine {
      action assignDays = assignDays
    
      initial state test {
        machine nested {
        }
      }
    }
    

    compiles to

    import { createMachine } from 'xstate';
    import { assignDays } from './utils.js';
    
    export function createTestMachine({ context = {} } = {}) {
      return createMachine({
        initial: 'test',
        context,
        states: {
          test: {
            context
          }
        }
      });
    }
    

    where actions dissapeared

    bug 
    opened by Santiago-j-s 2
  • Compile hangs if too many repeated event definitions

    Compile hangs if too many repeated event definitions

    I believe I've isolated this down. In the tableau state there are multiple repeated up and down transitions with different given guards. If you delete any two of those event transitions it'll correctly compile. With three or more present it'll hang the compiler.

    machine highlighted {
    
      guard isUnderStock = :isUnderStock
      guard isUnderWaste = :isUnderWaste
      guard isUnderFoundation = :isUnderFoundation
    
      initial state stock {
        up => tableau
        down => tableau
        left => foundation
        right => waste
      }
    
      state foundation {
        up => tableau
        down => tableau
    
        left => guard(:isStartOfFoundation) => waste
        left => foundation
    
        right => guard(:isEndOfFoundation) => stock
        right => foundation
      }
    
      state waste {
        up => tableau
        down => tableau
        left => stock
        right => foundation
      }
    
      state tableau {
        up => isUnderStock => stock
        up => isUnderWaste => waste
        up => isUnderFoundation => foundation
        up => tableau
    
        down => isUnderStock => stock
        down => isUnderWaste => waste
        down => isUnderFoundation => foundation
        down => tableau
    
        left => tableau
        right => tableau
      }
    }
    
    bug 
    opened by zephraph 1
  • Nested states without nested machines

    Nested states without nested machines

    I'm thinking that having nested states by nesting a machine is kind of strange. It's like a machine but also is completely tied to the outer. Does it make sense to just have states directly inside of states instead?

    opened by matthewp 2
  • [IDEA] XState JSON to Lucy?

    [IDEA] XState JSON to Lucy?

    Hi!! Thanks for you work!! It's been fun playing with Lucy 😊

    I was thinking would it be possible to generate Lucy files from XState JSON definitions? Not sure if it would be super complex or is something simple.

    I thought about it as I was replicating my XState machines in Lucy manually :)

    Thanks!

    enhancement 
    opened by santicros 8
Releases(v0.5.8)
The PULP Ara is a 64-bit Vector Unit, compatible with the RISC-V Vector Extension Version 0.9, working as a coprocessor to CORE-V's CVA6 core

Ara Ara is a vector unit working as a coprocessor for the CVA6 core. It supports the RISC-V Vector Extension, version 0.9. Dependencies Check DEPENDEN

null 185 Dec 24, 2022
An EDA toolchain for integrated core-memory interval thermal simulations of 2D, 2.5, and 3D multi-/many-core processors

CoMeT: An Integrated Interval Thermal Simulation Toolchain for 2D, 2.5D, and 3D Processor-Memory Systems With the growing power density in both cores

MARG 11 Sep 25, 2022
Arduino core for GD32 devices, community developed, based on original GigaDevice's core

GD32 Arduino Core (New) This is a Arduino core is based off of the original GigaDevice core that was provided by the company in early June 2021 (see h

null 46 Dec 24, 2022
JuCC - Jadavpur University Compiler Compiler

JuCC This is the official Jadavpur University Compiler Compiler repository. Key Features Supports a subset of the C language for now. Custom grammar f

Shuvayan Ghosh Dastidar 36 Sep 1, 2022
PL/0 to C compiler to teach basic compiler construction from a practical, hands-on perspective.

pl0c pl0c is a compiler for the PL/0 language. It reads in PL/0 source code and outputs equivalent C source code. It was written to be the subject of

Brian Callahan 100 Dec 30, 2022
Compiler Design Project: Simulation of front-end phase of C Compiler involving switch-case construct.

CSPC41 Compiler Design Project Assignment Compiler Design Project: Simulation of front-end phase of C Compiler involving switch-case construct. Using

Adeep Hande 1 Dec 15, 2021
The DirectX Shader Compiler project includes a compiler and related tools used to compile High-Level Shader Language (HLSL) programs into DirectX Intermediate Language (DXIL) representation

DirectX Shader Compiler The DirectX Shader Compiler project includes a compiler and related tools used to compile High-Level Shader Language (HLSL) pr

Microsoft 2.4k Jan 3, 2023
C-based/Cached/Core Computer Vision Library, A Modern Computer Vision Library

Build Status Travis CI VM: Linux x64: Raspberry Pi 3: Jetson TX2: Backstory I set to build ccv with a minimalism inspiration. That was back in 2010, o

Liu Liu 6.9k Jan 6, 2023
The d-SEAMS C++ core engine

d-SEAMS Deferred Structural Elucidation Analysis for Molecular Simulations Check our build status here. The docs themselves are here and development i

d-SEAMS 26 Oct 15, 2022
Cap'n Proto serialization/RPC system - core tools and C++ library

Cap'n Proto is an insanely fast data interchange format and capability-based RPC system. Think JSON, except binary. Or think Protocol Buffers, except

Cap'n Proto 9.5k Dec 30, 2022
C-based/Cached/Core Computer Vision Library, A Modern Computer Vision Library

Build Status Travis CI VM: Linux x64: Raspberry Pi 3: Jetson TX2: Backstory I set to build ccv with a minimalism inspiration. That was back in 2010, o

Liu Liu 6.9k Jan 6, 2023
ZeroMQ core engine in C++, implements ZMTP/3.1

ZeroMQ Welcome The ZeroMQ lightweight messaging kernel is a library which extends the standard socket interfaces with features traditionally provided

The ZeroMQ project 8.2k Jan 8, 2023
Cap'n Proto serialization/RPC system - core tools and C++ library

Cap'n Proto is an insanely fast data interchange format and capability-based RPC system. Think JSON, except binary. Or think Protocol Buffers, except

Cap'n Proto 9.5k Jan 1, 2023
The C++ Core Guidelines are a set of tried-and-true guidelines, rules, and best practices about coding in C++

The C++ Core Guidelines are a collaborative effort led by Bjarne Stroustrup, much like the C++ language itself. They are the result of many person-years of discussion and design across a number of organizations. Their design encourages general applicability and broad adoption but they can be freely copied and modified to meet your organization's needs.

Standard C++ Foundation 36.6k Jan 6, 2023
Minimal Linux Live (MLL) is a tiny educational Linux distribution, which is designed to be built from scratch by using a collection of automated shell scripts. Minimal Linux Live offers a core environment with just the Linux kernel, GNU C library, and Busybox userland utilities.

Minimal Linux Live (MLL) is a tiny educational Linux distribution, which is designed to be built from scratch by using a collection of automated shell scripts. Minimal Linux Live offers a core environment with just the Linux kernel, GNU C library, and Busybox userland utilities.

John Davidson 1.3k Jan 8, 2023
A 3GPP R16 compliant open source 5G core UPF (User Plane Function).

OpenUPF A 3GPP R16 compliant open source UPF. The OpenUPF is an open source project for 5th generation (5G) mobile core networks User Plane Function.

openupf 74 Dec 16, 2022
Bitcoin Core integration/staging tree

Bitcoin is an experimental digital currency that enables instant payments to anyone, anywhere in the world. Bitcoin uses peer-to-peer technology to operate with no central authority: managing transactions and issuing money are carried out collectively by the network. Bitcoin Core is the name of open source software which enables the use of this currency.

Bitcoin 67.6k Jan 4, 2023
SSD1306 library and simple graphics core library based on Adafruit GFX Library.

Raspberry Pico SSD1306 + GFX Library Based on Adafruit GFX Library https://github.com/adafruit/Adafruit-GFX-Library Usage Hardware Connect your SSD130

Marcin Bober 31 Sep 1, 2022