Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP Template-Haskell based version #233

Open
wants to merge 39 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
a0f3dc6
CodeCombinators package, produceActionTable with combinators
fleex-x Mar 5, 2022
414b583
Commit unstaged from previous commit
fleex-x Mar 5, 2022
ce71cab
add where section for CodeCombinators.clause
fleex-x Mar 6, 2022
fa087a3
rewrite produceExpListPerState using code-combinators
fleex-x Mar 6, 2022
313745c
Add associated type families to CodeGen class, move extensions to cab…
fleex-x Mar 7, 2022
5be4b65
split CodeCombinators module
fleex-x Mar 7, 2022
335411c
Code refactoring
fleex-x Mar 14, 2022
36a9c37
Add some useful combinators
fleex-x Mar 14, 2022
ac400e8
Rewrite some code in ProduceCode.lhs using simple combinators from pr…
fleex-x Mar 14, 2022
c3feb99
Add mkOpName in CodeGen class (because of parens for op name in DocEx…
fleex-x Mar 14, 2022
67dbf3c
Add instance CodeGen TH.Exp
fleex-x Mar 14, 2022
a69eac4
Add monad to CodeGen class for newNames generating
fleex-x Mar 15, 2022
f59ce78
Add hedgehog tests for DocExp generating
fleex-x Mar 21, 2022
61319a2
Add ArithSeqE for DocExp tests generating. Fix in Syntax.arithSeqE an…
fleex-x Mar 24, 2022
bf84ea9
Add generating 0-length list in hedgehog-tests
fleex-x Mar 25, 2022
66afd18
Rewrite produceExpListArray using code-combinators
fleex-x Mar 25, 2022
108a014
Modified getName (now it creates name if name doesn't exist in the map)
fleex-x Mar 25, 2022
65691aa
Rewrite produceExpListArray using newNames generating monad
fleex-x Mar 25, 2022
b63d15b
Add appManyArgsE for simple code-generation
fleex-x Mar 26, 2022
c6d8a23
Add appManyArgsT for simple code-generation
fleex-x Mar 26, 2022
9e56079
Add DocPat hedgehog tests. Fix bug with escaping in Syntax.litP
fleex-x Mar 26, 2022
5f83030
Add appManyArgsE to hedgehog tests
fleex-x Mar 28, 2022
58bd64e
Add hedgehog DocType generating tests
fleex-x Mar 28, 2022
3317663
Add hedgeog tests for [DocDec] generating. Fix bug in Syntax.clause.
fleex-x Mar 28, 2022
d6f0912
Fix new blank line at EOF
fleex-x Mar 29, 2022
b8a9f15
Fix order of extensions and etc in cabal file.
fleex-x Mar 29, 2022
99e0bb3
Fix Issue#2.
fleex-x Mar 29, 2022
800027b
Add (Monad (NewNameM e)) condition for CodeGen class.
fleex-x Mar 29, 2022
130406d
Add instance IsString (NameT e).
fleex-x Mar 29, 2022
ea109f1
Add fullFunD combinator to simplify code generation.
fleex-x Mar 29, 2022
abac97d
Remove redundant (Monad (NewNameM e)) from produceExpListArray context.
fleex-x Mar 29, 2022
2e6dca0
Fix some ghc warnings
fleex-x Mar 29, 2022
6a72c3d
Change type of intE
fleex-x Mar 29, 2022
f2db12e
Fix ghc warnings in code-combinators-tests
fleex-x Mar 29, 2022
650e74c
Add noInlinePragma generating function to CodeCombinators
fleex-x Mar 29, 2022
f18959a
Rewrite pragma inside produceExpListPerState with code-combinators
fleex-x Mar 29, 2022
500a045
Remove redundant where section
fleex-x Apr 16, 2022
a11071c
Rewrite produceExpListArray without using newName generating
fleex-x Apr 16, 2022
6cae39d
Remove redundant comment
fleex-x Apr 16, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions packages/backend-lalr/happy-backend-lalr.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,14 @@ library
Happy.Backend.LALR.ProduceCode
build-depends: base < 5,
array,
mtl > 2,
containers,
happy-codegen-common == 1.21.0,
happy-grammar == 1.21.0,
happy-tabular == 1.21.0
happy-tabular == 1.21.0,
happy-code-combinators == 1.21.0

default-language: Haskell98
default-extensions: CPP, MagicHash, FlexibleContexts
default-extensions: CPP, MagicHash, FlexibleContexts, OverloadedStrings
ghc-options: -Wall
other-modules: Paths_happy_backend_lalr
167 changes: 140 additions & 27 deletions packages/backend-lalr/src/Happy/Backend/LALR/ProduceCode.lhs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ The code generator.
> import Data.Array.MArray ( MArray(..), freeze, readArray, writeArray )
> import Data.Array.IArray ( Array, IArray(..), (!), array, assocs, elems )

> import Happy.Backend.CodeCombinators
> import Happy.Backend.CodeCombinators.Syntax

%-----------------------------------------------------------------------------
Produce the complete output file.

Expand Down Expand Up @@ -581,28 +584,118 @@ machinery to discard states in the parser...
> produceActionTable TargetArrayBased
> = produceActionArray
> . produceReduceArray
> . str "happy_n_terms = " . shows n_terminals . str " :: Prelude.Int\n"
> . str "happy_n_nonterms = " . shows n_nonterminals . str " :: Prelude.Int\n\n"
>
> . renderDocDecs [
> fullFunD "happy_n_terms" intT
> [clause [] (intE n_terminals) []]
> , fullFunD "happy_n_nonterms_name" intT
> [clause [] (intE n_nonterminals) []]
> ]
> . nl

> produceExpListPerState
> = produceExpListArray
> . str "{-# NOINLINE happyExpListPerState #-}\n"
> . str "happyExpListPerState st =\n"
> . str " token_strs_expected\n"
> . str " where token_strs = " . str (show $ elems token_names') . str "\n"
> . str " bit_start = st Prelude.* " . str (show nr_tokens) . str "\n"
> . str " bit_end = (st Prelude.+ 1) Prelude.* " . str (show nr_tokens) . str "\n"
> . str " read_bit = readArrayBit happyExpList\n"
> . str " bits = Prelude.map read_bit [bit_start..bit_end Prelude.- 1]\n"
> . str " bits_indexed = Prelude.zip bits [0.."
> . str (show (nr_tokens - 1)) . str "]\n"
> . str " token_strs_expected = Prelude.concatMap f bits_indexed\n"
> . str " f (Prelude.False, _) = []\n"
> . str " f (Prelude.True, nr) = [token_strs Prelude.!! nr]\n"
> . str "\n"
> =
> produceExpListArray
> . renderDocDecs [[noInlinePragmaD happy_exp_list_per_state_name, happy_exp_list_per_state_dec]]
> . nl
> where (first_token, last_token) = bounds token_names'
> nr_tokens = last_token - first_token + 1
>
> --happyExpListPerState st = token_strs_expected
> happy_exp_list_per_state_name = "happyExpListPerState"
> happy_exp_list_per_state_dec =
> funD happy_exp_list_per_state_name [
> clause [st_pat] (varE token_strs_expected_name) [
> token_strs_dec,
> bit_start_dec,
> bit_end_dec,
> read_bit_dec,
> bits_dec,
> bits_indexed_dec,
> f_dec,
> token_strs_expected_dec
> ]
> ]
>
> st_name = "st"
> st_var = varE st_name
> st_pat = varP st_name
>
> --token_strs = elems token_names'
> token_strs_name = "token_strs"
> token_strs_dec = funD token_strs_name [clause [] token_strs_exp []]
> where token_strs_exp = listE [stringE str_elem | str_elem <- elems token_names']
>
> --bit_start = st Prelude.* nr_tokens
> bit_start_name = "bit_start"
> bit_start_dec = funD bit_start_name [clause [] bit_start_exp []]
> where bit_start_exp = appManyArgsE mulE [st_var, intE nr_tokens]
>
> --bit_end = (st Prelude.+ 1) Prelude.* nr_tokens
> bit_end_name = "bit_end"
> bit_end_dec = funD bit_end_name [clause [] bit_end_exp []]
> where bit_end_exp = appManyArgsE mulE [appManyArgsE addE [st_var, intE 1], intE nr_tokens]
>
> --read_bit = readArrayBit happyExpList
> read_bit_name = "read_bit"
> read_bit_dec = funD read_bit_name [clause [] read_bit_exp []]
> where read_bit_exp = appE (varE "readArrayBit") (varE "happyExpList")
>
> --bits = Prelude.map read_bit [bit_start..bit_end Prelude.- 1]
> bits_name = "bits"
> bits_dec = funD bits_name [clause [] bits_exp []]
> where bits_exp =
> appManyArgsE
> (varE "Prelude.map")
> [
> varE read_bit_name
> , arithSeqE $
> FromToR
> (varE bit_start_name)
> (appManyArgsE subE [varE bit_end_name, intE 1])
> ]
>
> --bits_indexed = Prelude.zip bits [0... nr_tokens - 1]
> bits_indexed_name = "bits_indexed"
> bits_indexed_dec = funD bits_indexed_name [clause [] bits_indexed_exp []]
> where bits_indexed_exp =
> appManyArgsE
> (varE "Prelude.zip")
> [
> varE bits_name
> , arithSeqE $
> FromToR
> (intE 0)
> (intE $ nr_tokens - 1)
> ]
>
> --f (Prelude.False, _) = []\n"
> --f (Prelude.True, nr) = [token_strs Prelude.!! nr]\n
> f_name = "f"
> f_dec = funD f_name [clause1, clause2]
> where clause1 = clause [tupP [falseP, wildP]] emptyListE []
> clause2 = clause [tupP [trueP, varP nr]] exp2 []
> nr = "nr"
> exp2 =
> listE [
> appManyArgsE
> (varE "(Prelude.!!)")
> [
> varE token_strs_name
> , varE nr
> ]
> ]
>
> --token_strs_expected = Prelude.concatMap f token_strs_name = "token_strs"
> token_strs_expected_name = "token_strs_expected"
> token_strs_expected_dec = funD token_strs_expected_name [clause [] token_strs_expected_exp []]
> where token_strs_expected_exp =
> appManyArgsE
> (varE "Prelude.concatMap")
> [
> varE f_name
> , varE bits_indexed_name
> ]
>
> produceStateFunction goto' (state, acts)
> = foldr (.) id (map produceActions assocs_acts)
> . foldr (.) id (map produceGotos (assocs gotos))
Expand Down Expand Up @@ -726,16 +819,36 @@ action array indexed by (terminal * last_state) + state

> produceExpListArray
> | ghc
> = str "happyExpList :: HappyAddr\n"
> . str "happyExpList = HappyA# \"" --"
> . str (hexChars explist)
> . str "\"#\n\n" --"
> =
> -- happyExpList :: HappyAddr
> -- happyExpList = HappyA# "hexCharsE explist"#
> let happy_exp_list_exp =
> appE (conE "HappyA#") (hexCharsE explist)
> happy_exp_list_dec =
> fullFunD "happyExpList" (conT "HappyAddr")
> [(clause [] happy_exp_list_exp [])]
> in
> renderDocDecs [happy_exp_list_dec]
> | otherwise
> = str "happyExpList :: Happy_Data_Array.Array Prelude.Int Prelude.Int\n"
> . str "happyExpList = Happy_Data_Array.listArray (0,"
> . shows table_size . str ") (["
> . interleave' "," (map shows explist)
> . str "\n\t])\n\n"
> =
> -- happyExpList :: Happy_Data_Array.Array Prelude.Int Prelude.Int
> -- happyExpList = Happy_Data_Array.listArray (0, table_size) [explist]
> let happy_exp_list_type =
> appManyArgsT
> (conT "Happy_Data_Array.Array")
> [intT, intT]
> happy_exp_list_exp =
> appManyArgsE
> (varE "Happy_Data_Array.listArray")
> [
> tupE [intE 0, intE table_size]
> , listE $ intE <$> explist
> ]
> happy_exp_list_dec =
> fullFunD "happyExpList" happy_exp_list_type
> [(clause [] happy_exp_list_exp [])]
> in
> renderDocDecs [happy_exp_list_dec]

> (_, last_state) = bounds action
> n_states = last_state + 1
Expand Down
88 changes: 88 additions & 0 deletions packages/code-combinators/happy-code-combinators.cabal
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
name: happy-code-combinators
version: 1.21.0
license: BSD2
license-file: LICENSE
copyright: (c) Andy Gill, Simon Marlow
author: Artem Zakharenko
maintainer: Artem Zakharenko <[email protected]>
bug-reports: https://github.com/simonmar/happy/issues
stability: not-stable
homepage: https://www.haskell.org/happy/
category: Development
cabal-version: >= 1.10
build-type: Simple
synopsis: Code combinators for simple code generation

Description:
Happy is a parser generator for Haskell.
Happy-Backend-CodeCombinators allows to generate code
in both abstract and text represantation.


tested-with:
GHC == 9.2.1
GHC == 9.0.2
GHC == 8.10.7
GHC == 8.8.4
GHC == 8.6.5
GHC == 8.4.4
GHC == 8.2.2
GHC == 8.0.2
GHC == 7.10.3
GHC == 7.8.4
GHC == 7.6.3
GHC == 7.4.2
GHC == 7.0.4

library
hs-source-dirs: src

exposed-modules: Happy.Backend.CodeCombinators,
Happy.Backend.CodeCombinators.Abstract,
Happy.Backend.CodeCombinators.Syntax

build-depends: array,
base < 5,
containers,
mtl,
pretty,
template-haskell

default-language: Haskell98
default-extensions: CPP,
FlexibleContexts,
InstanceSigs,
KindSignatures,
MagicHash,
OverloadedStrings,
TypeFamilyDependencies

ghc-options: -Wall -Wno-orphans


test-suite test
type: exitcode-stdio-1.0
main-is: Test.hs
other-modules:
Test.CodeCombinators.Common
, Test.CodeCombinators.GenExp
, Test.CodeCombinators.GenDec
, Test.CodeCombinators.GenPat
, Test.CodeCombinators.GenType

hs-source-dirs:
test

default-extensions:
OverloadedStrings
, TemplateHaskell

ghc-options: -Wall
build-depends:
base < 5
, happy-code-combinators
, haskell-src-meta
, hedgehog
, template-haskell

default-language: Haskell98
Loading