GithubHelp home page GithubHelp logo

plick's Introduction

plick

A PL/1 Compiler for Microcomputers (Micro PL/1).

Plick is a LLVM Frontend Compiler for a very much work-in-progress dialect of PL/1 called Micro PL/1.

Install

Dependencies

  1. LLVM version 14.0
  2. A C compiler for linking (tested to work with both GCC and Clang)

Windows Setup

Tested on Windows 11

To make a working copy of plick from source, you will require a copy of LLVM 14.0. Plick's tests also requires C/C++ development tooling, such as MSVC or Mingw-w64. Because Rust also uses LLVM you already have one of these - by default, MSVC.

  • Follow these instructions to build LLVM from source and install on your machine.
  • Set the LLVM_SYS_140_PREFIX environment variable to the path of your built LLVM root to get the llvm-sys dependency working.

Once LLVM is set up, plick should be able to run. Note that by default the outputted object files will share the target of your current Rust toolchain. For most people on Windows, that means the object files will be for the x86_64-pc-windows-msvc target.

NOTE: cargo test on the MSVC toolchain assumes command-line access to Microsoft's cl compiler. The easiest way to provide access is to run cargo test from a Visual Studio Developer Command Prompt.

  • Compile a pli file from the project with cargo run -- <PATH TO FILE HERE>

  • Link the file to create the executable with the following command: cl <file name here> /link msvcrt.lib legacy_stdio_definitions.lib

  • You should now have an executable ready to run

Linux Setup

Tested on Debian 12 Bookworm

Install the following packages:

  • llvm-14-dev
  • libpolly-14-dev
  • zlib1g-dev
  • build-essential

Compile .pli files into .o files with cargo run -- <PATH TO FILE HERE>. Link to executable files with cc -o <OUTPUT FILE NAME> <PATH TO OBJ FILE HERE> -lm.

plick's People

Contributors

jblorincz avatar

Stargazers

 avatar

Watchers

 avatar

plick's Issues

Prelude

The prelude is just a llvm Module (and maybe some PL/1 standard library functions) that is implicitly included in all compiled PL/1 programs

Implement Get List()

Example

GET LIST (A,B,C,D,E);

This pops 5 args off of the stdin and places them in variables A, B, C, D, and E respectively.

These variables are assumed to be FLOAT DECIMAL because they are variables that begin with characters A through H, O through Z, or the symbols @ # and $.

Break up Codegen.rs

Codegen.rs is getting a bit unwieldy, i think each "codegenable" should get its own file in a "ast_implemenations" directory living underneath the codegen module

Break code into more modules

Parser.rs needs to be broken up into an ast file and a parser file, this will prepare things for a type system

Cleaning up Tests

Tests currently all live next to the code they are testing, this is fine in some cases but not when the testing code is 700 lines or more. The tests should be moved to a separate tests directory

Arbitrarily Sized Fixed Decimals

In PL/1 you can specify the number of digits a fixed number can have, like so:

DECLARE MEAN FIXED DECIMAL(4,1);

This creates a fixed decimal with a total of 4 digits and one fractional digit (one digit after the decimal point).

Currently, all fixed decimals have the same exact size. This will have to change.

Unwraps have no good error message

 unsafe fn generate_variable_code(&'a self,variable_name: &str) -> Result<Box<dyn AnyValue<'ctx> + 'ctx>, String>
        {
            let named_value: NamedValue<'ctx> = self.named_values.try_get(variable_name).unwrap();

If i misspell PUT as PUTe it panics here (codegen line 377)

Printing strings with extra space adds unintended things to stdout

checking the stdout of "putting_numbers.pli" results in this: "(3000000000000000)(0000000000000000)(3000000000000000)(4000000000000000)(5000000000000000)FINAL VALUETesty\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}\u{1}" with all of the untaken bits being printed as invisible characters

Type specific print functions

A good way to get around the printf pointer situation is to encapsulate all the printing logic inside its own IR function. This will enable passing a value so its automatically alloca'd, giving a pointer, and is also cleaned up when the function gets popped off the stack.

Implement proper statement handling

Currently, only the main function supports statements. User defined functions only support a singular expression which they implicitly return. It's time to improve user defined functions so they can support more than one statement

Parse Prototypes

Parse the definition of a function (not worrying about subroutines yet)

Improve scanner

Scanner has trouble with cases like 2+2 and 5/3 where the operator touches the numbers

Support negative numbers

Negative numbers:

  • Currently can't be parsed
  • Turn into really large positive numbers (due to assuming numbers are unsigned)

This needs to be fixed

User facing error system

Errors should be understandable and actionable to the user, with a clear criteria for what causes each error. The program should also be able to return more than one error and not just panic on a single error.

Case sensitivity

https://www.ibm.com/docs/en/epfz/5.3?topic=set-case-sensitivity

You can use a combination of lowercase and uppercase characters in a PL/I program.

When used in keywords or identifiers, the lowercase characters are treated as the corresponding uppercase characters. This is true even if you entered a lowercase character as a DBCS character.

When used in a comment or in a character, mixed, or a graphic string constant, lowercase characters remain lowercase.

Implement List()

List only exists in Get List and Put List (List Based IO).

Any type of PL/1 constant can appear in the input stream.

However, the Get has to be of the proper type. For example,

DECLARE CITY CHARACTER(12);
GET LIST(CITY);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.