~jojo/Carth

3fefe39f340b7e15a3ae5abd4d3459a3a05cd091 — JoJo 2 years ago aabfffa
Reimplement foreign core library in Rust

Because Rust is much nicer than C.
M README.org => README.org +11 -2
@@ 17,10 17,19 @@ Visit [[https://carth.jo.zone/][https://carth.jo.zone/]] for an overview of the 

* Building
  This project is written in [[https://haskell.org][Haskell]] and uses the [[https://www.haskellstack.org/][Stack]] build
  system. The external dependencies required are [[https://llvm.org/][LLVM]] version 8. To
  build the project, simply run ~stack build~. To install (copy the
  system. The external dependencies required are [[https://llvm.org/][LLVM]] version 9.

  To build the project, simply run ~stack build~. To install (copy the
  binary), run ~stack install~.

  The Carth compiler needs to link with a foreign core library of
  functions that can't be defined in Carth itself, to do things like
  input/output and pointer manipulation etc. This library is written
  in Rust and is located in "foreign-core/". Build with ~cargo build~,
  and copy the resulting static library from
  "foreign-core/target/debug/libcarth-foreign-core.a" to
  "foreign-core/".

* Running
  #+BEGIN_EXAMPLE bash
  # General help

M examples/test.carth => examples/test.carth +1 -33
@@ 1,34 1,2 @@
(type (List a)
  Nil
  (List a (List a)))

(type (Maybe a)
  None
  (Some a))

(define (main _)
  (let [[xs (List 42 (List 69 Nil))]]
    (match (bindMaybe head (tail xs))
      [(Some n) (printInt n)]
      [None     (printInt 666)])))

(define: (head xs)
    (forall [a] (Fun (List a) (Maybe a)))
  (match xs
    [Nil None]
    [(List x _) (Some x)]))

(define: tail
    (forall [a] (Fun (List a) (Maybe (List a))))
  (fun (ys)
    (match ys
      [Nil None]
      [(List _ xs) (Some xs)])))

(define: (bindMaybe f)
    (forall [a b] (Fun (Fun a (Maybe b))
                       (Maybe a)
                       (Maybe b)))
  (fun-match
    [(Some a) (f a)]
    [None None]))
  (print-int 123))

A foreign-core/.gitignore => foreign-core/.gitignore +1 -0
@@ 0,0 1,1 @@
target/
\ No newline at end of file

A foreign-core/Cargo.lock => foreign-core/Cargo.lock +5 -0
@@ 0,0 1,5 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "carth-foreign-core"
version = "0.1.0"

A foreign-core/Cargo.toml => foreign-core/Cargo.toml +14 -0
@@ 0,0 1,14 @@
[package]
name = "carth-foreign-core"
version = "0.1.0"
authors = ["JoJo <jo@jo.zone>"]
edition = "2018"
description = "The foreign part of Carths core"
homepage = "https://carth.jo.zone"
repository = "https://gitlab.com/JoJoZ/carth"
license = "AGPL-3.0"

[dependencies]

[lib]
crate-type = ["staticlib"]
\ No newline at end of file

A foreign-core/src/lib.rs => foreign-core/src/lib.rs +4 -0
@@ 0,0 1,4 @@
#[export_name = "print-int"]
pub extern "C" fn print_int(n: i64) {
    println!("{}", n)
}

M src/Check.hs => src/Check.hs +1 -1
@@ 72,7 72,7 @@ initEnv = Env

builtinSchemes :: Map String Scheme
builtinSchemes = Map.fromList
    [("printInt", Forall Set.empty (TFun (TPrim TInt) (TPrim TUnit)))]
    [("print-int", Forall Set.empty (TFun (TPrim TInt) (TPrim TUnit)))]

initSt :: St
initSt = St { _tvCount = 0, _substs = Map.empty }

M src/Codegen.hs => src/Codegen.hs +3 -3
@@ 170,7 170,7 @@ genBuiltins = map
        (mkName "malloc")
        [parameter (mkName "size") i64]
        (LLType.ptr typeUnit)
    , simpleFunc (mkName "printInt") [parameter (mkName "n") i64] typeUnit
    , simpleFunc (mkName "print-int") [parameter (mkName "n") i64] typeUnit
    ]

genOuterMain :: Gen' Definition


@@ 300,8 300,8 @@ genApp :: Expr -> Expr -> Gen Operand
genApp fe ae = do
    a <- genExpr ae
    case fe of
        Var (TypedVar "printInt" _) ->
            emitAnon (callExtern "printInt" typeUnit [a])
        Var (TypedVar "print-int" _) ->
            emitAnon (callExtern "print-int" typeUnit [a])
        _ -> do
            closure <- genExpr fe
            app closure a

M src/Compile.hs => src/Compile.hs +7 -1
@@ 45,7 45,13 @@ compileModule cfg m = withHostTargetMachinePIC $ \t -> do
    writeObjectToFile t (File ofile) m
    callProcess
        (cc cfg)
        ["-o", binfile, ofile, "/home/jojo/Hack/carth/lib/lib.c"]
        [ "-o"
        , binfile
        , ofile
        , "/home/jojo/Hack/carth/foreign-core/libcarth_foreign_core.a"
        , "-ldl"
        , "-lpthread"
        ]

withHostTargetMachinePIC :: (TargetMachine -> IO a) -> IO a
withHostTargetMachinePIC f = do

M src/Interp.hs => src/Interp.hs +1 -1
@@ 39,7 39,7 @@ runEval m = runReaderT m builtinValues

builtinValues :: Map TypedVar Val
builtinValues = Map.fromList
    [ ( TypedVar "printInt" (TFun (TPrim TInt) (TPrim TUnit))
    [ ( TypedVar "print-int" (TFun (TPrim TInt) (TPrim TUnit))
      , VFun (\v -> print (unwrapInt v) $> VConst Unit)
      )
    , ( TypedVar "+" (TFun (TPrim TInt) (TFun (TPrim TInt) (TPrim TInt)))