Skip to content

Instantly share code, notes, and snippets.

View robinp's full-sized avatar

Robin Palotai robinp

  • Budapest, Hungary
View GitHub Profile
@robinp
robinp / graph-bashing.sh
Last active September 4, 2017 19:59
Extract callgraph edges with awk
gunzip -c all.nq.gz | grep 'node/kind" "package' > packages.nq
gunzip -c all.nq.gz | awk 'NR==FNR { a[$1]; next } /childof/{if ($3 in a) print $1}' packages.nq - > pkgchildren.txt
gunzip -c all.nq.gz | awk 'NR==FNR { a[$1]; next } /childof/{if ($3 in a) print $1" "$3}' pkgchildren.txt - | gzip - > topchildren.txt.gz
gunzip -c all.nq.gz | awk 'NR==FNR { a[$1]=$2; mx=FNR; next } (NR-mx==FNR) { b[$1] ; next } /kythe\/edge\/ref/{if (($1 in a) && ($3 in b)) print a[$1]" "$3}' <(gunzip -c topchildren.txt.gz) pkgchildren.txt - | uniq | gzip - > callgraph.txt.gz
@robinp
robinp / ghc-api-reuse.md
Last active April 2, 2018 10:42
Calling GHC API multiple times: choose your ExitFailure

GHC API lets you process Haskell sources, and (among other) specify code generation and linking level. For example:

  • (1) no codegen & no link
  • (2) bytecode generation & link in memory
  • (3) machine code generation & linking output binaries

For code analysis purposes, based on generating the typechecked AST, option (1) suffices most of the time. There are some situations in which it doesn't:

  • TemplateHaskell (TH) splice needs to execute code (at compile time) from an imported module: the imported module must be available in compiled form, so either (2) or (3) is needed. Example: in $([|$(foo)|]), foo will be evaluated at compile-time.
  • Code uses FFI imports. For this one would expect that (2) is needed (see checkCOrAsmOrLlvmOrInterp in TcForeign.hs), but actually unless it is used (say by TH, see below), even (1) works too (see the wrapper checkCg).
@robinp
robinp / GhcWrapper.hs
Created July 13, 2017 20:38
Random GHC wrapper script.
import GHC.Paths
import System.Posix.Process
import System.Environment
import System.IO
import Data.List (intercalate)
import Control.Monad (when)
lg = appendFile "/tmp/fake.lg" . (++ "\n")
main = do
@robinp
robinp / ghc_wrapper.sh
Created June 30, 2017 20:36
Indexing GHC source
#!/bin/bash
# GHC wrapper for indexing Haskell packages.
# Note that variables INDEXER_OUTPUT_DIR and REALGHC are set outside this script.
log() {
echo "$1" >> "$INDEXER_OUTPUT_DIR/$PKG.log"
}
log "GHC $*"
@robinp
robinp / cayley-load.sh
Created June 30, 2017 20:24
Load Kythe data into Cayley
/opt/kythe/tools/triples --graphstore ~/dev/ghc-vagrant/entries/gs > entries.all
cayley init -db leveldb -dbpath cdb
cayley load -db leveldb -dbpath cdb -quads=entries.all -alsologtostderr
@robinp
robinp / ghc8-ast.txt
Last active June 14, 2017 20:22
GHC 8 AST changes
=== Recursive function with type signature
A recursive call (with typesig) targets the polymorphic binding (vs the monomorphic one usually targeted).
Now there's a new ctor for this kind of function (AbsBindsSig), having only a poly-like binding exposed.
Caveat: the internal FunBind still refers the monomorphic binding. So it's a bit less obvious to make the connection.
module Sphinx where
import Data.Text (Text)
import Foreign (alloca, peek)
import Foreign.C.String (CString)
import Foreign.Ptr (Ptr, nullPtr)
-- TODO move utils
peekIntegral = fmap fromIntegral . peek
@robinp
robinp / Lib.hs
Created January 15, 2017 12:30
Free error when building x
{-# LANGUAGE QuasiQuotes #-}
module Lib where
import NeatInterpolation
renderXmlRequest = [text|apple|]
@robinp
robinp / save-screen-to-gif.sh
Created August 29, 2016 17:54
How to save a screen region to gif.
# Need to install ffcast, and advisedly also xrectsel (on arch can do from AUR)
# Below command will let you select a region with the mouse, than stream it to ffmpeg.
# Many args magic (taken from SO), but allegedly it saves as lossless.
ffcast -s % ffmpeg -f x11grab -show_region 1 -framerate 20 -video_size %s -i %D+%c -codec:v huffyuv -vf crop="iw-mod(iw\\,2):ih-mod(ih\\,2)" out.avi
# Use ImageMagick to covert to gif - works great!
convert -set delay 5 -layers Optimize out.avi out.gif
@robinp
robinp / Lista.hs
Last active August 16, 2016 20:15
data Lista = Megtobb Int Lista | Vege
uresLista :: Lista
uresLista = Vege
egyKetHa :: Lista
egyKetHa = Megtobb 1 (Megtobb 2 (Megtobb 3 Vege))
hossz :: Lista -> Int
hossz Vege = 0