• Implementing built-in functions with LLVM, help needed

    From Ivan Espinosa@21:1/5 to All on Mon Oct 3 15:13:04 2022
    Hello,

    I'm currently working on a personal project about a front-end compiler
    for some sort of the old Pascal version to produce LLVM code. I'm kind
    of new to this amazing topic, and I would like to know how should I
    implement functions like writeln, read, etc. It would be very useful
    if somebody could help me with this giving some ideas or resources so
    I can work in that.

    Thank you all!
    Gerardo Espinosa

    PD: Here is the link to my project code
    https://github.com/IvanMtze/JAPC

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From [email protected]@21:1/5 to Ivan Espinosa on Thu Oct 6 15:15:44 2022
    Ivan Espinosa <[email protected]> wrote:
    Hello,

    I'm currently working on a personal project about a front-end compiler
    for some sort of the old Pascal version to produce LLVM code. I'm kind
    of new to this amazing topic, and I would like to know how should I
    implement functions like writeln, read, etc. It would be very useful
    if somebody could help me with this giving some ideas or resources so
    I can work in that.

    Built in functions in Pascal have special syntax, so you need
    approprate code in parser to recognize them. Easy trick is to
    have more general parsing for _all_ functions, but generate
    error after parsing when non-builtin function tries to use
    syntax reserved for builtins. Writeln, etc. allow variable
    number of arguments, but meaning is defined be equvalent
    sequence of one-argument calls. Your compiler needs to
    effectively replace single multiargument call by seqence
    of one or two argument calls. Basic fixed argument functions
    can be written in C or Pascal (if you have extentions to do
    system calls or calls to C library). There is extra difficulty:
    standard Pascal does not allow overloading for user defined
    functions, but buitin functions are overloaded. You can
    solve this in ad-hoc manner, having table which for each
    combination of arguments to builtin functions gives corresponding
    function in runtime library (in this apprach functions in runtime
    library have different names than builtins). This is essentially
    how GNU Pascal handles builtin calls. More elegant would be
    to support function/procedure overloading as compiler
    extention and write runtime library in extended language.
    However, in classic Pascal there is only handful of builtion
    functions so ad-hoc apprach _may_ be easier. OTOH IME implementing
    some feature inside compiler takes 5-10 times as much work as
    putting it in runtime library (when possible), and if you
    had overloading adding builtins would be much easier. Implementing
    general overloading requires some effort, depending on number
    of builtins and on specific implementaion choices it may be less
    or more work than ad-hoc approach to builtins.

    --
    Waldek Hebisch

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Christopher F Clark@21:1/5 to All on Fri Oct 7 08:56:19 2022
    I'm surprised no one has chimed in yet, so I will.

    How should I implement functions like writeln, read, etc?

    I presume you have a design for "user defined" functions and
    procedures. If not, you need that first. That is roughly how you pass
    in parameters and receive return values. Usually there is a convention
    (often defined by the OS or these days the C compiler) that one
    follows to do that.

    But once you have that, you can call functions. And, if it is a
    convention suitable for C, it specifies how you handle variadic
    functions, functions that take a variable number of arguments like
    writeln. Now, you may need some Pascal specific wrinkles because the
    Pascal language supports things like variables from the parent scope
    (a subset of the closure concept) and for writeln knowing the type of
    the variable passed so that you can format it properly
    ("descriptors").

    Still, the ability to call functions is the key thing you need to do.
    Once, you have that, you implement the "builtin" functions as
    functions. If your Pascal code is complete enough you can do it in
    Pascal, but quite often you do it in another (often lower level
    language like C). You don't actually generate the code directly from
    LLVM, other than doing a function call. Of perhaps a set of function
    calls, e.g. writeln might be call the "to_string" function for each
    parameter and then passing all those parameters to a function that
    writes a series of strings. But, both of those are simply functions
    that you call, not generally inline code sequences.

    -- ****************************************************************************** Chris Clark email: [email protected] Compiler Resources, Inc. Web Site: http://world.std.com/~compres
    23 Bailey Rd voice: (508) 435-5016
    Berlin, MA 01503 USA twitter: @intel_chris ------------------------------------------------------------------------------

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Hans-Peter Diettrich@21:1/5 to Christopher F Clark on Fri Oct 7 20:59:49 2022
    On 10/7/22 7:56 AM, Christopher F Clark wrote:

    Still, the ability to call functions is the key thing you need to do.

    And the compiler has to decide whether an argument type is okay, can be converted, or is incompatible with a function definition. So IMO
    handling of polymorphic and variadic functions is a matter of
    organisation of function argument types.

    DoDi

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From [email protected]@21:1/5 to Christopher F Clark on Thu Oct 13 14:08:15 2022
    Christopher F Clark <[email protected]> wrote:
    I'm surprised no one has chimed in yet, so I will.

    How should I implement functions like writeln, read, etc?

    I presume you have a design for "user defined" functions and
    procedures. If not, you need that first. That is roughly how you pass
    in parameters and receive return values. Usually there is a convention
    (often defined by the OS or these days the C compiler) that one
    follows to do that.

    But once you have that, you can call functions. And, if it is a
    convention suitable for C, it specifies how you handle variadic
    functions, functions that take a variable number of arguments like
    writeln.

    Treating writeln via variable argument call is wrong. Compiler
    is supposed to split writeln into separate simpler statements.
    This leads to subtle difference, folks trying to implement
    Pascal via C-like approach at some moment learn the difference
    and fix their compilers, but it is better to get it right the
    first time.

    Now, you may need some Pascal specific wrinkles because the
    Pascal language supports things like variables from the parent scope
    (a subset of the closure concept) and for writeln knowing the type of
    the variable passed so that you can format it properly
    ("descriptors").

    Syntax of buitins is different that normal calls, that is easy
    to handle in parser but must be done before call. And builtins
    are overloaded, in dialects with many builtins handling of
    overloading may take most of implementation.

    Still, the ability to call functions is the key thing you need to do.

    Sure.

    --
    Waldek Hebisch

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)