[Remove a backup of the old wiki, out of date information (the new wiki is backed up automatically) Neil Mitchell**20061026133230] { hunk ./wiki/Yhc.html 1 - - - - - - -Yhc - The Haskell Wiki - - - - - - - - - - - - - - - - - - -
UserPreferences
-

Yhc

- - - -
- - - -
-

Yhc - York Haskell Compiler

-

-http://www-users.cs.york.ac.uk/~ndm/yhc/yhc.png, see the official home page at http://www.cs.york.ac.uk/~ndm/yhc/ -

-

Yhc Manual

-

-This is the official Yhc manual, feel free to edit it! (you must be logged into edit) -

-
    -
  1. -

    -/Introduction - the dull stuff -

    -
  2. -
  3. -

    -/UsingYhc - short tutorial on yhc, yhi, yhe -

    -
  4. -
  5. -

    -/FAQ - Frequently Asked Questions -

    -
  6. -
  7. -

    -?/Options - command line options and environment variables -

    -
  8. -
  9. -

    -/Building - building yhc from source -

    -
  10. -
  11. -

    -/Hacking - how to hack on Yhc -

    -
  12. -
  13. -

    -/Porting - how to port Yhc to a new architecture/platform -

    -
  14. -
- -

License

-

-By adding anything under Yhc/*, you consent to it being licensed under a BSD license. Yhc itself (both compiler and runtime) are released under the GPL. Any programs compiled with Yhc do not gain any additional license restrictions. -

-

Yhc Pages

-

-These are all the pages within the Yhc domain -

-

-

- - -

-
-

-CategoryHaskellImplementations CategoryApplication -

-
- - - - - - - - rmfile ./wiki/Yhc.html hunk ./wiki/Yhc_2fBuilding.html 1 - - - - - - -Yhc/Building - The Haskell Wiki - - - - - - - - - - - - - - - - - - - -
UserPreferences
-

Yhc/Building

- - - -
- - - -
-

Yhc - Building

-

-

    -
  1. -Yhc - Building
  2. -
      -
    1. -Requirements
    2. -
    3. -Getting the Code
    4. -
    5. -Building on Windows
    6. -
    7. -Building on Linux/Unix
    8. -
    9. -Building on Mac OS X
    10. -
    - -
- - -

-

Requirements

-

-You need a C compiler - both gcc and MS Visual C are known to be OK. -

-

-If you want to build the yhc compiler itself (not strictly necessary), you will need a very recent Haskell compiler, e.g. ghc >= 6.4 or nhc98 >= 1.18. -

-

Getting the Code

-

-The first step is to get the source code. There are two branches, stable and development. Stable should always build and give you a working compiler, but development is the one we are putting new things into. We can't generally guarantee that the development branch will always even compile so stable is likely most useful to people. It is hoped that the stable branch will be no more than a week or so behind development. -

-

-The source code is stored in a darcs (http://www.darcs.net/) repo, to get the stable version do: -

- -
darcs get http://www.cs.york.ac.uk/fp/darcs/yhc/
-

-To get the development version do: -

- -
darcs get http://www.cs.york.ac.uk/fp/darcs/yhc-devel/
-

Building on Windows

-

-Open a console at the root of the yhc tree. There is a file called Makefile.bat, which is used to build the various components. Just typing Makefile should give you a list of the options. -

-

-The modes are: -

- - -

-The standard options are: -

- - -

-All compiled binaries will go into \inst\bin. To compile and run the test suite do: -

- -
$ Makefile yhc
-$ Makefile yhi
-$ Makefile yht
-$ Makefile test 98
-

Building on Linux/Unix

-

-The standard unix thing will should get you most of the way. -

- -
chmod +x configure   # because darcs does't record the executable bit
-./configure
-make
-

-There currently isn't a 'make install', but it is fairly trivial: simply copy the contents of the 'inst' directory into where everything should be installed. -

-

Building on Mac OS X

-

-You will need to have libraries like GMP (Gnu multi-precision arithmetic) installed. Most people do this with Fink or ?DarwinPorts, or some such. You need the header files in addition to the library archive, and these are often distributed in a 'devel' version of the package. -

-

-If your packaging system uses a separate directory hierarchy (Fink uses /sw) then you may need to set up some environment variables so that the C compiler can find the includes and libraries: -

LD_LIBRARY_PATH=/sw/lib    # for dylibs
-LIBRARY_PATH=/sw/lib       # for static linking
-CPATH=/sw/include          # for header files
-
-

-

-Then just follow the usual unix-like procedure, as above. -

-
- - - - - - - - rmfile ./wiki/Yhc_2fBuilding.html hunk ./wiki/Yhc_2fByteCodeApi.html 1 - - - - - - -Yhc/ByteCodeApi - The Haskell Wiki - - - - - - - - - - - - - - - - - - - -
UserPreferences
-

Yhc/ByteCodeApi

- - - -
- - - -
-

ByteCode API

-

-On the step towards a full API for the whole compiler, an API for just the bytecode first will probably be desirable. -

-

-There are two entirely separate lumps in this, the raw bytecode, and the wrappers that make a module file. -

-

Module

- -
-data Module = Module {objects :: [Object]}
-
-data PackageVer = PackageVer {version :: [Int], name :: String}
-data ModuleName = ModuleName PackageVer {name :: String}
-data Import = Import ModuleName {name :: String, arity :: Int}
-data Export = Export {name :: String, obj :: Object, arity :: Int}
-
-data Object = Function Arity ConstTable HufByteCode
-            | Constructor Arity TagNo
-
-type ConstTable = [Const]
-
-type HufByteCode = [HufBC]
-
- - -

- -

-

Bytecode

-

-There are tree types of bytecode representation: -

- -
-data GraphNode = ...
-data LabeledJumps = ...
-
- - -

- -

-

-Then there are the api's -

-instance Show GraphNode
-instance Show ByteCode
-instance Show ByteCodeHuf
-instance Show ...
-
-graphToByteCode :: GraphNode -> ByteCode
-byteCodeToGraph :: ByteCode -> GraphNode
-byteCodeCompress :: ByteCode -> ByteCodeHuf
-byteCodeInflate :: ByteCodeHuf -> ByteCode
-
-writeModule :: Module -> FilePath -> IO ()
-readModule :: FilePath -> IO Module
-
--- do memory and zapping analysis
-memAnalysis :: a -> a
-
--- peep hole optimisations
-peephole :: a -> a
-
- - - -

-
- - - - - - - - rmfile ./wiki/Yhc_2fByteCodeApi.html hunk ./wiki/Yhc_2fFAQ.html 1 - - - - - - -Yhc/FAQ - The Haskell Wiki - - - - - - - - - - - - - - - - - - - -
UserPreferences
-

Yhc/FAQ

- - - -
- - - -
-

Yhc FAQ

-

-Back to Yhc

    -
  1. -Yhc FAQ
  2. -
      -
    1. -In relation to nhc98
    2. -
    3. -Portability
    4. -
    - -
- - -

-

In relation to nhc98

-

-Q) What did you think needed changing from nhc98? -

-

-A) nhc98's backend had several problems (not portable to Windows, high memory bug). -

-

-Q) nhc98 had a small size and a simple implementation, what about yhc? -

-

-A) Yhc has simpler bytecodes (not by much, but by a bit) and is designed to have a simpler implementation. Yhc needs fewer bytecodes to encode a program, and executes each bytecode slightly faster. -

-

-Q) I was interested in nhc, should I now be more interested in yhc? -

-

-A) Good question. Unfortunately there isn't a good answer yet - try them both and see which one you like. -

-

-Q) Does the Yhc back-end support everything that the current nhc98 back-end does? -

-

-A) Not yet. Nhc98 supports heap and time profiling whereas this hasn't been implemented yet, more crucially the FFI support in yhc is also not ready yet. However, in terms of simple Haskell 98, yhc does everything nhc98 does. -

-

Portability

-

-Q) How portable is Yhc itself? -

-

-A) If your architecture has a C compiler that at least looks slightly ANSI C compliant, it should be a 10 minute port. In general most people have had the most trouble with the build system rather than the source code. It should certainly be possible to bootstrap yhc and we intend to provide makefiles for doing this soon. -

-

-Q) What about programs compiled by Yhc? -

-

-A) If you use sensible libraries - i.e. don't build up filepaths by ++, then you should be fine. If you use the FFI you will need to compile the FFI bits separate for every platform you support. -

-
- - - - - - - - rmfile ./wiki/Yhc_2fFAQ.html hunk ./wiki/Yhc_2fHacking.html 1 - - - - - - -Yhc/Hacking - The Haskell Wiki - - - - - - - - - - - - - - - - - - - -
UserPreferences
-

Yhc/Hacking

- - - -
- - - -
-

Yhc - Hacking

-

-Part of the Yhc Manual -

-

-First build Yhc - see Yhc/Building. If Yhc won't build on your architecture or platform using the supplied instructions, either hack the Makefile, or hack the instructions until it works perfect as described. -

-

Picking what to hack on

-

-Of course, most people who want to hack on Yhc probably already have something that Yhc doesn't do quite right for them. So thats often a good thing to think about. -

-

-If you have no idea, its often good to go onto the ?HaskellIrc channel, and talk to ndm / beelsebob / tomshackell - and i'm sure we can suggest something and help your understanding of some of the things. -

-

-There are various parts of Yhc, written in different languages, so pick the part that suits you: -

- - -

-Before you hack on anything substantial, its to avoid duplication it's probably best to mention it to someone on IRC, add it to the Yhc/Todo list, or email [WWW]the Yhc mailing list. -

-

Developer Documentation

- - -

Sending your patches

-

-Depending on what your patch does, send it to the following place using darcs send: -

- - -
- - - - - - - - rmfile ./wiki/Yhc_2fHacking.html hunk ./wiki/Yhc_2fHeapProfiling.html 1 - - - - - - -Yhc/HeapProfiling - The Haskell Wiki - - - - - - - - - - - - - - - - - - - -
UserPreferences
-

Yhc/HeapProfiling

- - - -
- - - -
-

Yhc - Heap Profiling

-

Lag, drag, void, use

-

-nhc98 had two pass compilation for this, lets try and do better :) -

-

-Assuming you have the lower level operations to detect when a node is collected, when it is used and when it is created: -

-

-node' = {node, time ?CreationTime, time ?FirstUse, time ?LastUse} -

-

-when a node' is created, it gets its creation time. -

-

-when a node' is used first, its ?FirstUse time gets set -

-

-when a note' is used ever, every single time, its gets its ?LastUse set. -

-

-When a node' is collected, its stats can be calculated: lag = firstuse-creation drag = now-lastuse void = if null creationtime then now-creation else 0 use = lastuse-firstuse -

-

-I guess the user will want to know which type of nodes, created by which function, are in any state at any discrete time point. This can be done with a set of accumulators, so effectively the graph is built in memory, then when a node' is collected it can be added to this list. -

-

-int graph[code][time]; where code is a list of all possible (function,type of node) pairs, and time is a list of discrete time steps. -

-

-This will require one pass running, does it miss anything? It doesn't say who holds onto the node, but it does the rest? -

-

--- NeilMitchell -

-
- - - - - - - - rmfile ./wiki/Yhc_2fHeapProfiling.html hunk ./wiki/Yhc_2fIdeas.html 1 - - - - - - -Yhc/Ideas - The Haskell Wiki - - - - - - - - - - - - - - - - - - - -
UserPreferences
-

Yhc/Ideas

- - - -
- - - -
-

[BOTTOM][TOP]Crazy ideas for Yhc

-

-This page lists entirely weird and crazy ideas, that probably shouldn't be implemented. However, if you don't write a thought down it might never come back. -

-

[BOTTOM][TOP]Have a via C generator

-

-Could Yhc generate C? Maybe from the .hbc file? It should speed things up considerably. Perhaps have a yho (York Haskell Optimiser) that takes the G-machine code and converts it into C? I guess a simple one should be quite easy to do, a more complex one that exploits stuff (i.e. no point pushing then adding, just add directly) would give better performance, without too much hassle. -

-

--- Neil -

-

[BOTTOM][TOP]Proof of concept port to Cell architecture

-

-People have sometimes commented that a language like Haskell might be a better language for programming a Cell-like cpu architecture than C since it is further from the low level details and so could adapt easier. -

-

-The Cell cpu architecture is difficult to code for in C because: -

- - -

-So it would be interesting to see if Haskell really can be implemented on this kind of architecture. For just a proof-oc-concept it would be a great deal easier to modify yhc to try this than ghc since the latter is much more complex. -

-

-So what might it look like? Well obviously yhc would need to be extended to support concurrent Haskell. -

-

-One problem with the 8 SPUs is that their local memory is very small. You would not want to waste space by having a full runtime system on each one. Each SPU should only run the "mutator" parts of the runtime system. Allocation of memory blocks and major GC collections would be deferred to the centeral CPU. -

-

-Like GHC's IO design (at least in the threaded rts), we would want to use an IO manager thread running on the centeral CPU to perform all IO operations on behalf of each SPU. This would also eliminate much of the rts that is needed to run code on each SPU. -

-

-The RTS on each SPU would have to deal with minor GC collections. The GC would use a generational scheme where some proportion of the SPU local memory would used for the first generation. The SPU local memory would be split between the first generaton and those bits of older generations which were currently being read. -

-

-The RTS of each SPU would need to be able to determine if a Haskell heap object was currently in local memory or if it needed to be fetched from main memory. Perhaps some software implementation of a TLB would be appropriate. It would also need to deal with 'paging' chunks between local and main memory to deal with accessing objects from older GC generations. -

-

-If the RTS were particularly clever it might arrange for threads which are in a MVar reader/writer relationship to be scheduled on ajacent SPUs since these have faster access to each others local memory. -

-
- - - - - - - - rmfile ./wiki/Yhc_2fIdeas.html hunk ./wiki/Yhc_2fIntroduction.html 1 - - - - - - -Yhc/Introduction - The Haskell Wiki - - - - - - - - - - - - - - - - - - - -
UserPreferences
-

Yhc/Introduction

- - - -
- - - -
-

Yhc Introduction

-

-Back to Yhc -

-

-Yhc is (C) 1996-2005 its contributors, which include Tom Shackell, Neil Mitchell, Tom Davie, Mike Dodds and more. -

-

-Yhc is substantially based on nhc98, which is (C) Niklas Röjemo, 1991-1998. Many parts of the nhc98 compiler, libraries, and build system were contributed or modified by Malcolm Wallace, Jan Sparud, David Wakeling, Colin Runciman, Phil Hassall, Olaf Chitil, and Thomas Nordin, and are copyright to them, their respective institutions, or funding bodies, (C) 1996-2004. -

-

-Yhc is released under the GPL, but programs compiled with Yhc are free from additional copyright restrictions. -

-
- - - - - - - - rmfile ./wiki/Yhc_2fIntroduction.html hunk ./wiki/Yhc_2fOptions.html 1 - - - - - - -Yhc/Options - The Haskell Wiki - - - - - - - - - - - - - - - - - - - -
UserPreferences
-

Yhc/Options

- - - -
- - - -
-

-Create this page -

-

-Alternatively, use one of these templates: -

- - -

-To create your own templates, add a page with a name matching the regex "[a-z]Template$". -

-
-

The following pages with similar names already exist...

7 matches for "Yhc/Options"

15 matches for "Yhc..."

- - - - - - - - rmfile ./wiki/Yhc_2fOptions.html hunk ./wiki/Yhc_2fPorting.html 1 - - - - - - -Yhc/Porting - The Haskell Wiki - - - - - - - - - - - - - - - - - - - -
UserPreferences
-

Yhc/Porting

- - - -
- - - -
-

Yhc Porting

-

-This describes how to port Yhc to a new architecture. It does not describe building which is covered in Yhc/Building, and should probably be read before this. -

-

Requirements

-

-The target system must have an ANSI compliant (ish) C compiler (i.e. GCC) that can produce binaries for that platform. Whether you can cross compile C, or native compile C is not an issue. -

-

Steps

-

Compile yhi

-

-Compile the runtime system, this is written in ANSI C. You will need a config.h file, which can either be generated from configure, or written by hand. If you need to make further changes to the source code, please send patches or bug reports. The standard build method is using a Makefile, although manually compiling and linking every *.c file also works fine. -

-

Finished

-

-Once yhi is running, you can use the cross platform version of yhc, as a .hbc file, and you have a haskell compiler on your target system. Of course, on an embeded system it is unlikely that you will want the haskell compiler as well. -

-
- - - - - - - - rmfile ./wiki/Yhc_2fPorting.html hunk ./wiki/Yhc_2fPorts.html 1 - - - - - - -Yhc/Ports - The Haskell Wiki - - - - - - - - - - - - - - - - - - - -
UserPreferences
-

Yhc/Ports

- - - -
- - - -
-

Yhc - Ports

-

-For a guide to porting Yhc see Yhc/Porting -

-

-Unless otherwise stated, all ports should work straight from the darcs repo, without any additional modifications - i.e. they are completed. -

- - -
- - - - - - - - rmfile ./wiki/Yhc_2fPorts.html hunk ./wiki/Yhc_2fRTS.html 1 - - - - - - -Yhc/RTS - The Haskell Wiki - - - - - - - - - - - - - - - - - - - -
UserPreferences
-

Yhc/RTS

- - - -
- - - -
-

Documentation for Yhc's Runtime System

-

-This document aims to give a brief overview of the structure of the Yhc runtime system. Hopefully with the help of this and the source code it should be possible for people to understand and make changes to the runtime system should they wish to do so. -

-

Overall Layout

-

-The runtime system is divided into several parts. -

- - -
- - - - - - - - rmfile ./wiki/Yhc_2fRTS.html hunk ./wiki/Yhc_2fRTS_2fBytecodeFormat.html 1 - - - - - - -Yhc/RTS/BytecodeFormat - The Haskell Wiki - - - - - - - - - - - - - - - - - - - -
UserPreferences
-

Yhc/RTS/BytecodeFormat

- - - -
- - - -
-

Yhc .hbc Bytecode File Format

-

-FIXME: needs more explanation. -

- -
  struct HbcFile {
-    Header          header;
-    StringTable     strings;
-    QualifId        moduleName;
-    ObjectTable     objects;
-  };
-

Header

- -
  struct Header {
-    Char           magic[4];        /* 'H' 'S' 'B' 'C' */
-    UShort         majorVersion;
-    UShort         minorVersion;
-    UShort         zero;            /* 0 */
-    UShort         numObjects;      
-  };
-

StringTable

- -
  struct StringTable {
-    UShort         numStrings;
-    String         strings[numStrings];
-  };
-
-
  struct String {
-    UShort         length;
-    Char           data[length];
-  };
-

ObjectTable

- -
  struct ObjectTable {
-    Object         objects[numObjects];
-  };
-
-
  struct Object {
-    QualifId      name;
-    UShort        length;
-    Char          data[length];
-  };
-

-The first byte of the 'data' section identifies the object type. Depending on the object type the rest of the data for and object has different structures. -

-
Object types
- -
  'F'            function object (FunObj)
-  'C'            constructor object (ConObj)
-  'P'            primitive object (PrimObj)
-  'X'            external object (ExtObj)
-

FunObj

- -
  struct FunObj {
-    Char        type;                 /* 'F' */
-    UByte       arity;
-    UShort      stack;
-    ConstTable  consts;
-    UShort      codeLength;
-    UByte       code[codeLength];
-  };
-
-
  struct ConstTable {
-    UShort     numConsts;
-    Constant   consts[numConsts];
-  };
-
-
  struct Constant {
-    Char      type;
-    Char      constData[??];
-  };
-

-The type of the constant identifies the size and type of the rest of the constant data. -

-
Constant Types
- -
  Type   Name      ConstData         Desc
-
-  'A'    CAF       FullyQualifId     Reference to a CAF node
-  'F'    FUN       FullyQualifId     Reference to a FInfo
-  '0'    FUN0      FullyQualifId     Reference to a zero arity FInfo
-  'C'    CON       FullyQualifId     Reference to a CInfo
-  'Z'    ZCON      FullyQualifId     Reference to a zero arity constructor node
-  'P'    PRIM      FullyQualifId     Reference to a primitive function (XInfo)
-  'X'    EXT       FullyQualifId     Reference to an external function (XInfo)
-  'i'    INT       Int               Int constant
-  'l'    INTEGER   Integer           Integer constant
-  'f'    FLOAT     Float             Float constant
-  'd'    DOUBLE    Float             Double constant
-  's'    STRING    String            String constant
-

ConObj

- -
  struct ConObj {
-    Char      type;          /* 'C' */
-    UByte     size; 
-    UByte     tag;        
-  };
-

PrimObj

- -
  struct PrimObj {
-    Char           type;         /* 'P' */
-    FullyQualifId  name;
-  };
-

ExtObj

- -
  struct ExtObj {
-    Char          type;          /* 'X' */
-    String        cName;         
-    UShort        arity;
-  };
-

FullyQualifId

- -
  struct FullyQualifId {
-    QualifId     module;
-    QualifId     item;
-  };
-

QualifId

- -
  struct QualifId {
-    UByte       length;
-    UShort      stringIndexs[length];
-  };
-

Integer

- -
  struct Integer {
-    SByte      length;
-    UByte      data[abs(length)];
-  };
-

-If length < 0 then the whole Integer is negative. -

-

Float

- -
  struct Float {
-    Integer   mant;
-    Short     exp;
-  };
-
- - - - - - - - rmfile ./wiki/Yhc_2fRTS_2fBytecodeFormat.html hunk ./wiki/Yhc_2fRTS_2fBytecodes.html 1 - - - - - - -Yhc/RTS/Bytecodes - The Haskell Wiki - - - - - - - - - - - - - - - - - - - -
UserPreferences
-

Yhc/RTS/Bytecodes

- - - -
- - - -
-

Yhc Bytecode Instructions

-

-The Yhc runtime is a stack-based spineless G-Machine (See Yhc/RTS/Machine). This page details the instruction set that the machine uses. -

-

-A more up to date page is at http://www-users.cs.york.ac.uk/~ndm/yhc/bytecodes.html, which is automatially generated from the bytecode.xml file. -

-

-Instructions have 'variants', which are different specializations of the instruction: For example if the general instruction is PUSH n then -

- - -

-Some instructions don't have three byte versions. Here 'PUSH n' refers to the two byte version, or the general 'PUSH n' instruction, depending on context. -

-

-The compiler will choose the smallest available bytecodes to encode any particular instruction. -

-

END_CODE

-

-variants: END_CODE -

-

-This instruction is placed at the end of every function, after the RETURN/RETURN_EVAL. If it is executed the machine will crash with an error. The idea is that if the mutator accidentally starts running non-code (for example because the compiler mis-generated a JUMP instruction) then the program will exit swiftly. The value of this instruction code being 0 aids in this. -

-

NEED_HEAP

-

-variants: NEED_HEAP_32, NEED_HEAP n -

-

-NEED_HEAP specifies the number of heap words required to run the whole of the next basic block (which is calculated by the compiler). Here the number of words required is given by n*32, or in the case of NEED_HEAP_32 it is assumed to be less than or equal to 32 words (if we've got less than 32 words left then a GC is needed anyway). -

-

-If the required number of words is available then NEED_HEAP does nothing, otherwise it calls the GC to try and free up the requested quantity of heap. If there still isn't enough the program terminates. -

-

PUSH

-

-variants: PUSH_0 .. PUSH_1, PUSH_P1 n, PUSH_P2 n -

-

-PUSH takes the nth argument on the stack and pushes the same pointer onto the top. So: -

- -
PUSH n         s_1 .. s_n : ss  ==> 
-         s_n : s_1 .. s_n : ss
-

ZAP_STACK and PUSH_ZAP

-

-variants: ZAP_STACK_P1 n, ZAP_STACK_P2 n -

- - -

-ZAP_STACK simply replaces the nth stack item with a pointer to a 'Prelude._zap_stack'. This is used to help prevent space leaks: when a value is no longer needed its stack reference can be 'zapped'. If this was the last reference to an object then if the GC runs it can collect the unused application. -

-

-If _zap_stack is evaluated it will terminate the program as this signifies that the compiler issued instructions to zap something too early. -

-

-PUSH_ZAP n is simply an abbreviated form for -

      PUSH n ; ZAP_STACK (n+1)
-
because this is such a common operation. -

-

PUSH_ARG

-

-variants: PUSH_ARG_0 .. PUSH_ARG_3, PUSH_ARG n -

-

-PUSH_ARG n pushes the nth argument of the 'current application node' (See Yhc/RTS/Machine) onto the top of the stack. -

-

ZAP_ARG and PUSH_ZAP_ARG

-

-variants: ZAP_ARG_0 .. ZAP_ARG_1, ZAP_ARG n -

- - -

-ZAP_ARG n replaces the nth argument of the 'current application node' with an application to 'Prelude._zap_arg'. PUSH_ZAP n is equivilent to -

- -
   PUSH_ARG n ; ZAP_ARG n
-

PUSH_INT and PUSH_CHAR

-

-variants: PUSH_INT_0 .. PUSH_INT_1, PUSH_INT_P1 n, PUSH_INT_P2 n -

- - -

-PUSH_INT n allocates a heap node for the Int n and pushes a pointer to the heap node on the top of the stack. PUSH_CHAR n does the same for the Char n. -

-

PUSH_CONST

-

-variants: PUSH_CONST_0 .. PUSH_CONST_7, PUSH_CONST_P1 n, PUSH_CONST_P2 n -

-

-PUSH_CONST n pushes the nth item of the current application node's constant table onto the top of the stack. This constant item must be a C_NODE rather than a C_INFO (See Yhc/RTS/Heap). -

-

MK_AP

-

-variants: MK_AP_0 .. MK_AP_15, MK_AP_P1 n, MK_AP_P2 n -

-

-MK_AP n looks up the nth item of the constant table (which must be a FInfo). It then makes a fully saturated application to this function by taking m arguments off the stack (where m is the arity of the function). It then builds an application in the heap to the given function with those arguments. It then pushes a pointer to the new application onto the top of the stack. -

- -
  MK_AP n        s_1 .. s_m : ss ==>
-                          a : ss                 
-
-  where
-  a is the new application of the given function to the arguments s_1 .. s_m  
-  m is the arity of the function described by constant table item n.
-

MK_PAP

-

-variants: MK_PAP_P1 n m, MK_PAP_P2 n m -

-

-MK_PAP n m is a more generalised version of MK_AP that can also build partial applications. As with MK_AP here n refers to the nth constant table item, but unlike MK_AP the arity of the application is specified explicitly in m. -

- -
  MK_PAP n m    s_1 .. s_m : ss ==>
-                         a : ss
-

APPLY

-

-variants: APPLY_1 .. APPLY_2, APPLY n -

-

-APPLY n takes an application on the top of the stack an application to additional n arguments from the stack to create a new application. -

- -
  APPLY n      a : s_1 .. s_n : ss ==>
-                            b : ss
-

-If applying an extra n arguments to the application a would super-saturate it (i.e. apply it to more arguments that the functions arity) then APPLY satures the application fully and then builds further applications to the built in function '_apply' to apply the rest of the argument. -

-

-The function '_apply' is defined in src/runtime/BCKernel/primitive.c as: -

- -
  _apply(app,arg):
-     NEED_HEAP_32
-     PUSH_ZAP arg
-     PUSH_ZAP app
-     EVAL
-     APPLY 1
-     RETURN_EVAL
-

-which is to say it evaluates the fully-staturated application which then returns another application, and this application is then applied to the additional argument. -

-

MK_CON

-

-variants: MK_CON_0 .. MK_CON_3, MK_CON_P1 n, MK_CON_P2 n -

-

-MK_CON n looks up the nth item of the constant table (which must be a CInfo). It then builds a fully saturated application to the constructor using the correct number of arguments from the stack. -

- -
  MK_CON n    s_1 .. s_m : ss ==>
-                       a : ss
-  where
-  a is the application to the constructor given by constant table item n
-  m is the arity of the constructor
-

UNPACK

-

-variants: UNPACK -

-

-UNPACK takes from the top of the stack an application to a constructor. It then pushes on the stack all the arguments of that constructor with the first argument on top. -

- -
  UNPACK            a : ss ==>
-           c_1 .. c_m : ss 
-  where
-  c_1 .. c_m are the arguments of the constructor application a
-  m is the arity of the application a
-

SLIDE

-

-variants: SLIDE_1 .. SLIDE_2, SLIDE_P1 n, SLIDE_P2 n -

-

-SLIDE n takes the top item off the stack, pops n items from the stack and then pushes the first item removed back on to the top of the stack -

- -
  SLIDE n   s : s_1 .. s_n : ss ==>
-                         s : ss
-

POP

-

-variants: POP_P1 n, POP_P2 n -

-

-POP n removes n items from the top of the stack. -

- -
  POP n      s_1 .. s_n : ss ==>
-                          ss
-

ALLOC

-

-variants: ALLOC_P1 n, ALLOC_P2 n -

-

-ALLOC n creates n 'blackhole' applications in the heap and pushes the pointers to the applications on to the top of the stack. -

- -
  ALLOC n                ss ==>
-            a_1 .. a_n : ss
-  where
-  a_1 .. a_n are 'blackhole' applications.
-

-The applications are to the function 'Prelude._black_hole' which will terminate the program if evaluated. -

-

-ALLOC n is used in conjunction with UPDATE n to create circular heap nodes. For example -

- -
repeat x = xs
-  where
-  xs = x : xs
-

-would be compiled as -

- -
 repeat(x):                      []
-   ALLOC 1                       [ hole ]
-   PUSH 0                        [ hole, hole ]
-   PUSH_ZAP_ARG x                [ x, hole, hole ]
-   MK_CON (:)                    [ x : hole, hole ]
-   UPDATE 0                      [ x:x:x:... ]
-   PUSH_ZAP 0                    [ x:x:x:..., ZAP ]
-   RETURN
-

UPDATE

-

-variants: UPDATE_P1 n, UPDATE_P2 n -

-

-UPDATE n removes the top item from stack and uses it to 'update' the application pointed to by the nth item of the stack. To 'update' the application it is overwritten with an application the value from the top of the stack. -

- -
  UPDATE n         a : s_1 .. s_n : ss ==>
-                       s_1 .. s_n : ss
-
-  where
-  the application at s_n is overwritten with an indirection to a
-

-UPDATE is used in conjunction with ALLOC to create cyclic memory structures. -

-

SELECT

-

-variants: SELECT_0 .. SELECT_1, SELECT_P1 n, SELECT_P2 n -

-

-SELECT n is an abbreviation for -

- -
  UNPACK ; PUSH_ZAP n ; RETURN_EVAL
-

-It is used to implement dictionaries and selectors. -

-

RETURN

-

-variants: RETURN -

-

-RETURN returns the value on the top of the stack as the result of the current function call. It then pops the top item off the frame stack to continue the function below it (see Yhc/RTS/Machine). -

-

EVAL

-

-variants: EVAL -

-

-EVAL takes the value on the top of the stack and evaluates it to weak head normal form (WHNF). If the value on the top of the stack is a constructor or partial application EVAL does nothing. If it is a saturated application then EVAL 'calls' the function specified in the application. It does this by pushing a new frame onto the stack (See Yhc/RTS/Machine). -

-

RETURN_EVAL

-

-variants: RETURN_EVAL -

-

-RETURN_EVAL is equivilent to -

- -
  EVAL ; RETURN 
-

-except that it doesn't use any stack space. RETURN_EVAL is thus used to implement tail call optimisation. -

-

TABLE_SWITCH

-

-variants: TABLE_SWITCH size jump-table -

-

-TABLE_SWITCH examines the tag of the item on the top of the stack and then jumps forward by the number of bytes specified by jump-table[tag]. -

-

LOOKUP_SWITCH and INT_SWITCH

-

-variants: LOOKUP_SWITCH size def lookup-table -

- - -

-LOOKUP_SWITCH is similar to TABLE_SWITCH but here lookup-table is an array of tag-offset pairs. When a matching tag is found the program jumps forward by 'offset' number of bytes. If no match is found the program just forward by 'def' number of bytes. -

-

-INT_SWITCH is similar to LOOKUP_SWITCH but selects on the integer value of an int node rather than on the constructor tag number. -

-

JUMP_FALSE

-

-variants: JUMP_FALSE j -

-

-JUMP_FALSE j removes the value from the top of the stack and if it is the node Prelude.False then the program jumps forward by j bytes. If it is not Prelude.False then JUMP_FALSE is a no-op. -

-

JUMP

-

-variants: JUMP j -

-

-JUMP j unconditionally jumps forward by j bytes. -

-

STRING

-

-variants: STRING -

-

-STRING removes from the top of the stack a pointer to an application to a ?StringNode. It then 'unpacks' the string into the equivilent list of characters. -

- -
  STRING                    s : ss ==>
-          (c:_primCString s') : ss
-
-  where
-  c is the first character of s
-  s' is the StringNode of the rest of the characters in s
-

-_primCString is a function to unpack more or the string and is defined in src/runtime/BCKernel/primitive.c as -

- -
  _primCString(s):
-     NEED_HEAP_32
-     PUSH_ZAP_ARG s
-     STRING
-     RETURN
-

FROM_ENUM

-

-variants: FROM_ENUM -

-

-FROM_ENUM takes a pointer to an application to a constructor from the top of the stack and pushes onto the top of the stack a pointer to an heap allocated Int containing the tag number of the constructor. -

-

-FROM_ENUM is used (perhaps rather unsurprisingly) to implement fromEnum -

-

PRIMITIVE

-

-variants: PRIMITIVE -

-

-PRIMITIVE takes the first constant table item, which must be an XInfo and calls the external function using the current application node. It pushes on the top of the stack the value returned by the external function. -

-

-PRIMITIVE is used to implement primitive functions and the FFI. -

-

SELECTOR_EVAL

-

-variants: SELECTOR_EVAL -

-

-SELECTOR_EVAL is an abbreviation for -

- -
  PUSH_ARG_0 ; EVAL
-

arithmetic

-

-variants: op_W, op_F, op_D where op is ADD, SUB, MUL, DIV, MOD, NEG -

-

-The arithmetic instructions take the appropriate number of integer, float or double applications from the stack and perform the appropriate operation; pushing the appropriate result onto the top of the stack. -

-

comparison

-

-variants: op_W, op_F, op_D where op is EQ, NE, LE, LT, GE, GT -

-

-The comparison instructions are similar to the arithmetic instructions but instead push a reference to either Prelude.True or Prelude.False -

-
- - - - - - - - rmfile ./wiki/Yhc_2fRTS_2fBytecodes.html hunk ./wiki/Yhc_2fRTS_2fHeap.html 1 - - - - - - -Yhc/RTS/Heap - The Haskell Wiki - - - - - - - - - - - - - - - - - - - -
UserPreferences
-

Yhc/RTS/Heap

- - - -
- - - -
-

Yhc Runtime System Heap

-

-The Yhc heap is a garbage collected area of memory in which the running program introduces heap nodes. In this document I will try to use 'heap' to exclusively mean this garbage collected part of the heap. Any other memory used by Yhc will be refered to as 'memory'. -

-

Heap Node structure

-

-The only kind of structure in the Yhc heap are heap nodes. The structure of heap nodes is defined in src/runtime/BCKernel/node.h -

-

-Every heap node is layed out in memory as -

- -
   +----------+----------+ . . +----------+
-   |  header  |  arg 0   |     |  arg n   |
-   +----------+----------+ . . +----------+
-

-Where each block is exactly one machine word. The header is a bit packed structure with layout -

- -
   n                     2    0 
-   +---------------------+----+
-   |  info ptr           | fl | 
-   +---------------------+----+
-

-The node flags (fl) occupy bits 0 and 1 of the header, with the rest taken by the info ptr. -

-

Node flags

-

-To understand the meaning of the node flags it's necessary to consider the life cycle of a heap node. There are two types of heap nodes 'constructors'(CON) and 'applications'. Applications are either partial applications (PAP) or thunks awaiting evaluation (THUNK). Constructors are simple data items created by the program. -

-

-Constructors have a very simple life cycle, they are introduced into the heap and eventually they are no longer needed and are garbage collected. Applications are more complicated: -

- - -

-The node flags of a node reflect this life cycle: there are four possible values for the 2 flag bits, indicating the different states of the node. -

- -
  0 0    IND     This node is an indirection, 'info ptr' points to the result.
-  0 1    NORMAL  This is a normal node, 'info ptr' points to the info table.
-  1 0    GC      This flag has special meaning to the garbage collector (see ["Yhc/RTS/Gc"])
-  1 1    HOLE    This is a heap node which is currently under evaluation, 'info ptr' points to info table.
-

-Ignoring the GC flag, a constructor always has 'NORMAL' flags (or GC if it's being used in GC) and an application goes from NORMAL -> HOLE -> IND. -

-

Node Info

-

-Every heap node which is a 'NORMAL' or a 'HOLE' has an info pointer. This pointer points to information (stored in memory, not the heap) about the heap node (representing by the structure Info in node.h). Most importantly it is the Info structure which identifies the type of the heap node: CON, THUNK or PAP. -

- -
  struct _Info {
-    UShort    tag;
-  };
-

-Tag is a half-word indicating what type of info this is, there are four possible values: -

- -
  * CINFO      information about a constructor (node is a CON)
-  * PINFO      information about an application (node is THUNK/PAP)
-  * FINFO      information about a function (no node will have this info directly, it'll be a PAP instead)
-  * XINFO      information about an external function (again, no node will have this info directly)
-

-If the tag of an 'info ptr' is a CINFO that the info ptr actually points to a CInfo structure, if the tag is PINFO it points to a PInfo structure, etc. -

-
CInfo
-

-The CInfo structure has the following layout: -

- -
  struct CInfo {
-    UShort       tag;     /* 'inherited' from Info */
-    UShort       size;    /* number of arguments to the constructor */
-    Char*        name;    /* name of the constructor */
-    UShort       number;  /* tag number: e.g. 0 for False, 1 for True, etc. */
-    UShort       flags;   /* flags controlling GC */
-  };
-

-flags is a combination of properties about the constructor which aid garbage collection: -

- -
   CI_NO_PTRS      the arguments of the constructor do not contain pointers (so don't follow them in GC).
-   CI_INTEGER      this is actually an integer (and thus variably sized).
-   CI_ARRAY        this is actually an array (and thus also variably sized).
-   CI_FOREIGN_PTR  this is a foreign ptr (and so requires special treatment in the 'mark' phase).
-
PInfo
-

-Information about an application to some function -

- -
  struct PInfo {
-    UShort          tag;   /* inherited from Info */
-    UByte           size;  /* the number of arguments does this application has */
-    UByte           need;  /* the number of arguments this application is missing */
-  };
-

-Which function this is an application to is not encoded directly in the PInfo structure and is instead stored by laying out things careful in memory. The information about a function (both PInfo and FInfo structures) is always layed out as: -

-
{ 
-     +-----------------+
-     | PInfo   0 / n   |            size 0, need n
-     +-----------------+
-     | PInfo   1 / n-1 |            size 1, need n-1
-     +-----------------+
-             ...
-     +-----------------+
-     | PInfo   n / 0   |            size n-1, need 0
-     +-----------------+
-     | FInfo   ....    |            function info table
-     .                 .
-     .                 .
-

-This way the corresponding FInfo for a given PInfo is given by -

- - -

-this is calculated by the PINFO_FINFO macro in node.h -

-
FInfo
-

-Information about a function: no application will have an info pointer directly to a FInfo, instead it'll point to a PInfo from which the FInfo can be found. -

- -
  struct FInfo {
-    UShort       tag;        /* inherited from Info */
-    PInfo*       papTable;   /* pointer back to the first item in the paptable for this function */
-    FInfo*       link;       /* used by the GC */
-    UShort       arity;      /* function arity */
-    UShort       stack;      /* unused - formely function stack usage */
-    Char*        name;       /* function name */
-
-    CodePtr      code;       /* pointer to the bytecode instructions for this function */
-    UShort       numConsts;  /* number of constants in the constant table */
-    UByte*       constTypes; /* pointer to a table of constant table type information */
-    ConstItem*   constTable; /* constant table constants */
-  };     
-

-Every function has a constant table which holds references to global objects that can be referenced by a function. For example a function such as: -

- -
  f = g (1 : [])
-

-would need a reference to the FInfo for 'g', as well as the CInfo for ':' and the heap node that represents '[]'. These references are stored in the constant table. -

-

-There are two types of object in the constant table: references to nodes in the heap (C_NODE) and references to other Info structures (C_INFO). The types of each constant are given by the bytes of 'constTypes': each byte gives the type of consequetive constant table items. -

-

-The constTable itself is an array of ?ConstItems which are pointers to either heap nodes or Info structures (obviously depending on the constant type). -

-

-NOTE: it is by recursively scanning the constant table of a functions that the module loading system knows what entries to load from the bytecode file (see Yhc/RTS/Modules) -

-
XInfo
-

-XInfo is very similar to a FInfo except it refers to an external (i.e. primitive or FFI) function. The only difference is that instead of a code pointer and constant table it has a C function pointer to the external function. The function is assumed to be of the form: -

-

-Node* function(Node*); -

-

-Where the function takes the application node (including arguments) and returns the application node of the result (see ?Yhc/RTS/Primitive and ?Yhc/RTS/Foreign). -

-
- - - - - - - - rmfile ./wiki/Yhc_2fRTS_2fHeap.html hunk ./wiki/Yhc_2fRTS_2fMachine.html 1 - - - - - - -Yhc/RTS/Machine - The Haskell Wiki - - - - - - - - - - - - - - - - - - - -
UserPreferences
-

Yhc/RTS/Machine

- - - -
- - - -
-

Yhc Virtual Machine Architecture

-

-The Yhc runtime is a stack machine based on the spineless G-Machine. For a detailed description of the individual machine instructions see Yhc/RTS/Bytecodes. -

-

-The stack machine has several major components: -

- - -

Registers

-

-The stack machine uses 'registers' (i.e. C variables) to store important information about the running state of the machine (see src/runtime/BCKernel/mutator.c). -

-

-The stack machine works by evaluating application nodes. Application nodes are calls to a given function with a given set of arguments. At any one time some application node (and thus some function) is 'currently under evaluation'. When a function is called it executes the bytecode instructions in that function which might cause the further evaluation of more application nodes. Eventually an application will produce a result and evaluation of an earlier application will continue. -

-

-The registers used in this process are: -

- - -

Heap

-

-The layout of heap nodes is described in Yhc/RTS/Heap and garbage collection in ?Yhc/RTS/GC. -

-

-The heap is layed out in memory as: -

- -
  +------------>-----------<----------+
-  | heap->     |           |  <-stack |
-  +------------>-----------<----------+
-  a            b           c          d
-

-where -

- - -

-The meaning of some of these registers is described below in 'Global registers'. -

-

-The heap and the stack grow towards each other and garbage collection is performed when they would overlap. -

-

Stack

-

-The program stack is used to store previous values of the machine registers in stack frames. This is used to allow nested function calls. The program stack is also used to during evaluation to perform calculation and as temporary store. The layout of the stack might thus be something like -

- -
 ===================
-  |   frame 0     |
-  +---------------+
-  :  stack data   :
-  +---------------+
-  |   frame 1     |
-  +---------------+ 
-  |   frame 2     |     <- fp
-  +---------------+     
-  :  stack data   :
-  :...............:
-  :  stack data   :     <- sp
-  :---------------:
-

-The structure of a single stack frame is: -

  struct Frame {
-    Frame*     fp;     /* saved value of the fp register */
-    CodePtr    ip;     /* saved value of the ip register */
-    Node*      vapptr; /* saved value of the vapptr register */
-  };
-
When a new node is evaluated a new frame is pushed on top of the stack. The current values of the registers are saved in the frame and the registers get new values: -

- - -

-When the function returns: -

-
    -
  1. -

    -the value on the top of the stack is saved temporarily -

    -
  2. -
  3. -

    -ip and vapptr are set to the value saved in the current frame -

    -
  4. -
  5. -

    -fp is set the value saved in the current frame -

    -
  6. -
  7. -

    -constptr is set to the constant table of vapptr -

    -
  8. -
  9. -

    -sp is set to the new value of fp -

    -
  10. -
  11. -

    -the value saved earlier is pushed back onto the top of the stack -

    -
  12. -
- -

-Since the stack grows into the heap running out of stack is not treatedly differently from running out of heap. -

-

Global registers

-

-There are some additional registers that are used (see src/runtime/BCKernel/heap.h): -

- - -

-There are also global registers that act as 'caches'. Which is to say they are globally visible copies of mutator registers (it's necessary to copy them back and from when moving in/out of the mutator). -

- - -
- - - - - - - - rmfile ./wiki/Yhc_2fRTS_2fMachine.html hunk ./wiki/Yhc_2fRTS_2fModules.html 1 - - - - - - -Yhc/RTS/Modules - The Haskell Wiki - - - - - - - - - - - - - - - - - - - -
UserPreferences
-

Yhc/RTS/Modules

- - - -
- - - -
-

YHC Module Loading

-

-In YHC modules are loaded at runtime by yhi (Yhc/UsingYhc) from .hbc bytecode files. For a precise specification of the bytcode format see Yhc/RTS/BytecodeFormat. -

-

-This file details how the loading process works, to see what structures are loaded into memory by the module system see Yhc/RTS/Heap. -

-

Loading by demand

-

-The program starts by loading the module with the 'main' function in it. Statically main will have a list of functions that it might call at runtime, these functions are loaded and there dependencies chased similarly. This is all handled by the code in "module.c" in src/runtime/BCKernel. -

-

-Yhi is careful to only load functions from the bytecode that could potentially be used, so as to minimize runtime memory use. Resolution then proceeds as follows: -

- - -
- - - - - - - - rmfile ./wiki/Yhc_2fRTS_2fModules.html hunk ./wiki/Yhc_2fTodo.html 1 - - - - - - -Yhc/Todo - The Haskell Wiki - - - - - - - - - - - - - - - - - - - -
UserPreferences
-

Yhc/Todo

- - - -
- - - -
-

Yhc Todo

-

-Todo list for Yhc -

-

Unassigned

- - -

Tom Shackell

-

-irc=tomshackell -

- - -

Neil Mitchell

-

-irc=ndm, wiki=NeilMitchell, web=http://www.cs.york.ac.uk/~ndm/ -

- - -

Bob Davie

-

-irc=beelsebob, wiki=?TomDavie, web=http://www.cs.kent.ac.uk/people/rpg/tatd2, email=tatd2@kent.ac.uk -

- - -

Mike Dodds

-

-web=http://www.cs.york.ac.uk/~miked/ -

- - -
- - - - - - - - rmfile ./wiki/Yhc_2fTodo.html hunk ./wiki/Yhc_2fUsingYhc.html 1 - - - - - - -Yhc/UsingYhc - The Haskell Wiki - - - - - - - - - - - - - - - - - - - -
UserPreferences
-

Yhc/UsingYhc

- - - -
- - - -
-

Yhc - Using Yhc

-

Obtaining Yhc

-

-Either download a binary distribution, or compile it from source (see Yhc/Building). A binary distribution is probably easier, but there aren't any yet until the first release. -

-

Setting the Package Path

-

-The easiest way to use Yhc is to first set the YHC_PACKAGE_PATH environment variable to the root of the packages. <say how to do this, give an example> -

-

Compiling Hello World

-

-Take a sample file, HelloWorld.hs -

- -
=========== File HelloWorld.hs ===============
-
-module Main where
-
-main = putStrLn "Hello, World!\n"
-
-==============================================
-
-
$ yhc HelloWorld
-$ yhi HelloWorld
-Hello, World!
-

yhc

-

-The yhc command takes a haskell source file, and generate a haskell bytecode file (extension, .hbc). The program always runs in make mode - so it will compile all requirements automatically. -

-

yhi

-

-The yhi command runs a haskell byte code file. -

-

yhe

-

-Yhe provides a Haskell 'command line' powered by Yhc. A gtk GUI also exists. -

-
- - - - - - - - rmfile ./wiki/Yhc_2fUsingYhc.html hunk ./wiki/Yhc_2fYhcApi.html 1 - - - - - - -Yhc/YhcApi - The Haskell Wiki - - - - - - - - - - - - - - - - - - - -
UserPreferences
-

Yhc/YhcApi

- - - -
- - - -
-

Yhc - Yhc API

-

-I want an API to Yhc, Ghc has one, and I don't want the other compiler authors laughing at us :) -

- -
-
--- first stage, lexing!
-data Pos = Pos {file :: FileName, line :: Int, pos :: Int}
-data Lex = {- Lexemes -} | InlineComment String | MultilineComment String | WhiteSpace String
-type LexPos = (Lex, Pos)
-
-lex :: String -> [LexPos] -- lex Haskell bits
-lexAll :: String -> [LexPos] -- also lex white space and comments
-
-
-output :: ParseTree -> [LexPos] -> String
-
--- QUESTION:
--- should the standard lexer just lex white space, and pass it onwards
--- what about moving to BLG?
--- that will handle bracketing first, then lexing
--- you can always run the BLG in Lex only mode, just not do it that way for the compiler
--- or offer to dump the bracketed version out before higher merging has been done
-
--- ONE OPTION:
--- lexOnly - not used by the compiler at all, using the lex phase plus some additional rules?
---           maybe entirely separate, just distribute a stadalone lexer if people want it?
--- bracketLex - first step, as the compiler does it - a bracketLex tree, possibly with comments/spaces
-
--- Group should not be run when spaces and comments are in the source!
--- would anyone ever want the source with just lexing, i.e. before bracketing?
-
--- we want round tripping, converting from input to output, can that be done?
-
-
-
-
-
-data ParseTree = ... | Position Pos ParseTree
-
-data Lex = ... | Comment String
-
-data Pos = Pos String Int Int
-
--- maybe with an annotation mechanism
-data ParseTree x = ... | ParseAnnotation x (ParseTree x)
-
-
-parse :: FilePath -> IO ParseTree
-lexer :: FilePath -> IO [(Pos, Lex)]
-
-dependancies :: ParseTree -> IO [FilePath]
-
-typeCheck :: ParseTree -> TypedParseTree
-
-desugar :: ParseTree -> ParseTree
-
-desugarCase :: ParseTree -> ParseTree
-desugarListComprehension :: ParseTree -> ParseTree
-
-
-bytecode :: ParseTree -> ByteCode
-
--- we were gonig to have a separate bytecode manip library, maybe put that in here?
-
-
- - -

- -

-

Round Tripping

-

-You want to parse the code to the parse tree, modify it in some way, then write it out again. How? -

-

-Options: lex returns everything, whitespace and comments included. Then have a parse tree phase. A modified parse tree can go back and look at the lex, along with the positions of the parse tree elements, and decide where things should end up. -

-

-But this assumes using lex first, which we don't want - we want preprocess, bracket, lex group (at least i do, and i will fight for this). so how? You can still lex, take the tokens returned from lex, intersperse them with the ?ParseTree, then write them out again. It means "lex/bracketing" the whole thing twice, but really, is that a problem? It will not be done by the compiler, but would be done by the type annotator, by ?HaRe, and I'm sure we can think of a few more utilities. Round tripping would be really nice. -

-

Users

-

-Potential or real, just use cases really so we make sure we've got all the functionality -

-

Catch

-

-Formal verifier for haskell programs. Will want parsing, no type checking, desugaring. Finding out where desugared lumps came from is important. -

-

HaRe

-

-Refactorer. Important to be able to output the syntax tree again, with comments intact and with indentation preserved exactly as it was before. -

-

Salmon

-

-Like haddock. Important to see comments, and be able to attach them. Type checker would be very handy. -

-
- - - - - - - - rmfile ./wiki/Yhc_2fYhcApi.html hunk ./wiki/Yhc_2fYhe.html 1 - - - - - - -Yhc/Yhe - The Haskell Wiki - - - - - - - - - - - - - - - - - - - -
UserPreferences
-

Yhc/Yhe

- - - -
- - - -
-

The York Haskell Evaluator

-

-Yhe is a command-line style tool in the vein of Ghci and Hugs. It consists of a command-line tool, yhe, and a GUI, Gyhe, written using gtk2hs. It was mostly written by [WWW]Mike Dodds. -

-

-Features of Gyhe: -

- - -

Todo

-

-General: -

- - -

-GUI: -

- - -

-Speculative / Moon on a stick: -

- - -

Bugs

- - -

Screenshots

-

-http://www-users.cs.york.ac.uk/~miked/images/gyhe_sceengrab2.jpg -

-

-http://www-users.cs.york.ac.uk/~miked/images/gyhe_sceengrab1.jpg -

-
- - - - - - - - rmfile ./wiki/Yhc_2fYhe.html hunk ./wiki/Yhc_2fYhiApi.html 1 - - - - - - -Yhc/YhiApi - The Haskell Wiki - - - - - - - - - - - - - - - - - - - -
UserPreferences
-

Yhc/YhiApi

- - - -
- - - -
-

Yhc - Yhi Api

-

-Some people want an Api for Yhi. It's needed for a good version of Yhe. -

-

Load a module

- -
//Load a module from an array of bytes
-Module loadModule(const char* Data, int Length);
-
-//Load a module from a file
-Module loadModuleFromFile(const char* FileName);
-

Running Main

- -
-data Console = Console {
-    stdout :: Char -> IO (),
-    stderr :: Char -> IO (),
-    stdin  :: IO Char
-  }
-
-runMain :: Module -> Console -> IO ()
-
-runMainThread :: Module -> Console -> IO () -> IO (IO ())
-
--- result is an action that when applied aborts the computation.
--- There is also an IO that is evaluated when the program terminates cleanly.
-
-
- - -

- -

-

-Apparently GtkHs does this, uses ?FunPtr, grep for "foreign .*wrapper" - see FfiCookbook -

-
- - - - - - - - rmfile ./wiki/Yhc_2fYhiApi.html hunk ./wiki/backup.bat 1 -wget http://www.haskell.org/hawiki/Yhc --html-extension --recursive --level=1 --include-directories=hawiki -copy www.haskell.org\hawiki\yhc*.* . - rmfile ./wiki/backup.bat rmdir ./wiki }