Last active
August 29, 2015 14:16
-
-
Save haskellcamargo/2941bb4cd9b217439f9b to your computer and use it in GitHub Desktop.
Harbour Prelude
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* This file is responsible by the preprocessor definitions and macros for | |
* work on syntax. | |
* @lastmod: 2015-03-13 | |
* @author : Marcelo Haskell Camargo | |
*/ | |
// Range syntax: @{ nStart .. nEnd } | |
#xtranslate @{ <nStart> .. <nEnd> } => Z_Range( <nStart>, <nEnd> ); | |
// Range syntax with step: @{ nStart, nNext .. nEnd } | |
#xtranslate @{ <nStart>, <nNext> .. <nEnd> } => ; | |
Z_StepRange( <nStart>, <nEnd>, <nNext> ) | |
// Specify Prelude functions to not affect the whole system, following the same | |
// principles of Protheus user's functions. | |
#xtranslate Prelude Function <cNome> => Function Z_<cNome> | |
#xtranslate @<cName> { <arg1> } => Z_<cName>( <arg1> ) | |
#xtranslate @<cName> { <arg1>, <arg2> } => Z_<cName>( <arg1>, <arg2> ) | |
#xtranslate @<cName> { <arg1>, <arg2>, <arg3> } => ; | |
Z_<cName>( <arg1>, <arg2>, <arg3> ) | |
// Special notation for calls | |
#xtranslate @<cName> <cList> ::= <expr> => ; | |
Z_<cName>( <expr>, <cList> ) | |
// <func> Of <list> | |
#xtranslate @<cName> <expr> Of <aList> => ; | |
Z_<cName>( <expr>, <aList> ) | |
// Binding, like Haskell | |
#xtranslate <cF> >>= <cG> In <expr> => <cF>( <cG>( <expr> ) ) | |
// Syntactic sugar for aAdd | |
#xtranslate <cVar>\[\] := <expr> => aAdd( <cVar>, <expr> ) | |
/** | |
* A port of Haskell's/Livescript's Prelude library | |
* for handling lists and data | |
* @lastmod: 2015-03-13 | |
* @author : Marcelo Haskell Camargo | |
*/ | |
// #include "PreludeSyntax.ch" | |
/** | |
* +=====================+ | |
* | List Handling | | |
* +=====================+ | |
*/ | |
Prelude Function Range( nStart, nEnd ) | |
Local aAccum := { } ; | |
, nI | |
For nI := nStart To nEnd | |
aAdd( aAccum, nI ) | |
Next nI | |
Return aAccum | |
Prelude Function StepRange( nStart, nEnd, nNext ) | |
Local aAccum := { } ; | |
, nI | |
For nI := nStart To nEnd Step (nNext - nStart) | |
aAdd( aAccum, nI ) | |
Next nI | |
Return aAccum | |
/** | |
* Applies a function to each item in the list, and produces a new list with | |
* the results. The length of the result is the same | |
* length as the input. | |
* @param : bBlock :: Block | |
* @param : aList :: Array | |
* @type : (a -> b) -> [a] -> [b] | |
* @return : Array | |
* @test : Pass | |
*/ | |
Prelude Function Map( bBlock, aList ) | |
Local aAccum := Array( Len( aList ) ) ; | |
, nI | |
For nI := 1 To Len( aList ) | |
aAccum[ nI ] := Eval( bBlock, aList[ nI ] ) | |
Next nI | |
Return aAccum | |
/** | |
* Applies a function to each item in the list and returns the original list. | |
* Used for side effects. | |
* @param : bBlock :: Block | |
* @param : aList :: Array | |
* @type : (a -> Undefined) -> [a] -> [a] | |
* @return : Array | |
* @test : Pass | |
*/ | |
Prelude Function Each ( bBlock, aList ) | |
Local nI | |
For nI := 1 To Len( aList ) | |
Eval( bBlock, aList[ nI ] ) | |
Next nI | |
/** | |
* Returns a new list which contains only the truthy values of the inputted | |
* list. | |
* @param : aList :: Array | |
* @type : [a] -> [a] | |
* @return : Array | |
* @test : Pass | |
*/ | |
Prelude Function Compact( aList ) | |
Local aAccum := { } ; | |
, nI | |
For nI := 1 To Len( aList ) | |
If aList[ nI ] | |
aAdd( aAccum, aList[ nI ] ) | |
EndIf | |
Next nI | |
Return aAccum | |
/** | |
* Returns a new list composed of the items which pass the supplied function's | |
* test. | |
* @param : bBlock :: Block | |
* @param : aList :: Array | |
* @type : (a -> Boolean) -> [a] -> [a] | |
* @return : Array | |
* @test : Pass | |
*/ | |
Prelude Function Filter( bBlock, aList ) | |
Local aAccum := { } ; | |
, nI | |
For nI := 1 To Len ( aList ) | |
If Eval( bBlock, aList[ nI ] ) | |
aAdd( aAccum, aList[ nI ] ) | |
EndIf | |
Next nI | |
Return aAccum | |
/** | |
* Like filter, but the new list is composed of all the items which fail the | |
* function's test. | |
* @param : bBlock :: Block | |
* @param : aList :: Array | |
* @type : (a -> Boolean) -> [a] -> [a] | |
* @return : Array | |
* @test : Pass | |
*/ | |
Prelude Function Reject( bBlock, aList ) | |
Local aAccum := { } ; | |
, nI | |
For nI := 1 To Len ( aList ) | |
If !Eval( bBlock, aList[ nI ] ) | |
aAdd( aAccum, aList[ nI ] ) | |
EndIf | |
Next nI | |
Return aAccum | |
/** | |
* Equivalent to [(filter f, xs), (reject f, xs)], but more efficient, using | |
* only one loop. | |
* @param : bBlock :: Block | |
* @param : aList :: Array | |
* @type : (a -> Boolean) -> [a] -> [[a], [a]] | |
* @return : Array | |
* @test : Pass | |
*/ | |
Prelude Function Partition( bBlock, aList ) | |
Local aAccum := { { }, { } } ; | |
, nI | |
For nI := 1 To Len( aList ) | |
If Eval( bBlock, aList[ nI ] ) | |
aAdd( aAccum[ 1 ], aList[ nI ] ) | |
Else | |
aAdd( aAccum[ 2 ], aList[ nI ] ) | |
EndIf | |
Next nI | |
Return aAccum | |
/** | |
* Equivalent to [(filter f, xs), (reject f, xs)], but more efficient, using | |
* only one loop. | |
* @param : bBlock :: Block | |
* @param : aList :: Array | |
* @type : (a -> Boolean) -> [a] -> Maybe a | |
* @return : xItem | |
* @test : Pass | |
*/ | |
Prelude Function Find( bBlock, aList ) | |
Local nI | |
For nI := 1 To Len( aList ) | |
If Eval( bBlock, aList[ nI ] ) | |
Return aList[ nI ] | |
EndIf | |
Next nI | |
Return Nil | |
/** | |
* The first item of the list. Returns undefined if the list is empty. | |
* @param : aList :: Array | |
* @type : [a] -> Maybe a | |
* @return : xItem | |
* @test : Pass | |
*/ | |
Prelude Function Head( aList ) | |
Return aList[ 1 ] | |
/** | |
* Everything but the first item of the list. | |
* @param : aList :: Array | |
* @type : [a] -> [a] | |
* @return : Array | |
* @test : Pass | |
*/ | |
Prelude Function Tail( aList ) | |
Return aDel( aList, 1 ) | |
/** | |
* Everything but the last item of the list. | |
* @param : aList :: Array | |
* @type : [a] -> [a] | |
* @return : Array | |
* @test : Pass | |
*/ | |
Prelude Function Initial( aList ) | |
Local aAccum := Array( Len( aList ) - 1 ) ; | |
, nI | |
For nI := 1 To ( Len( aList ) - 1 ) | |
aAccum[ nI ] := aList[ nI ] | |
Next nI | |
Return aAccum | |
/** | |
* Returns a new list which is the reverse of the inputted one. | |
* @param : aList :: Array | |
* @type : [a] -> [a] | |
* @return : Array | |
* @test : Pass | |
*/ | |
Prelude Function Reverse( aList ) | |
Local aAccum := { } ; | |
, nI | |
For nI := Len( aList ) To 1 Step -1 | |
aAdd( aAccum, aList[ nI ] ) | |
Next nI | |
Return aAccum | |
/** | |
* Concatenates a list of lists together. | |
* @param : aList :: Array | |
* @type : [[a]] -> [a] | |
* @return : Array | |
* @test : Pass | |
*/ | |
Prelude Function Concat( aList ) | |
Local aAccum := { } ; | |
, nI, nJ | |
For nI := 1 To Len( aList ) | |
For nJ := 1 To Len( aList[ nI ] ) | |
aAdd( aAccum, aList[ nI ][ nJ ] ) | |
Next nJ | |
Next nI | |
Return aAccum | |
/** | |
* Returns false if any item in the list is false, otherwise returns true. | |
* @param : aList :: Array | |
* @type : [a] -> Bool | |
* @return : Logic | |
* @test : Fail | |
*/ | |
Prelude Function AndList( aList ) | |
Local nI | |
For nI := 1 To Len( aList ) | |
If !aList[ nI ] | |
Return .F. | |
EndIf | |
Next nI | |
Return .T. | |
Prelude Function OrList( aList ) | |
Local nI | |
For nI := 1 To Len( aList ) | |
If aList[ nI ] | |
Return .T. | |
EndIf | |
Next nI | |
Return .F. | |
Prelude Function Any( bBlock, aList ) | |
Local nI | |
For nI := 1 To Len( aList ) | |
If Eval( bBlock, aList[ nI ] ) | |
Return .T. | |
EndIf | |
Next nI | |
Return .F. | |
Prelude Function All( aList ) | |
Local nI | |
For nI := 1 To Len( aList ) | |
If !aList[ nI ] | |
Return .F. | |
EndIf | |
Next nI | |
Return .T. | |
Prelude Function Sort( aList ) | |
Return aSort( aList ) | |
Prelude Function Sum( aList ) | |
Local nSum := 0 ; | |
, nI | |
For nI := 1 To Len( aList ) | |
nSum += aList[ nI ] | |
Next nI | |
Return nSum | |
Prelude Function Product( aList ) | |
Local nProd := 1 ; | |
, nI | |
For nI := 1 To Len( aList ) | |
nProd *= aList[ nI ] | |
Next nI | |
Return nProd | |
Prelude Function Mean( aList ) | |
Local nSum := 0 ; | |
, nI | |
For nI := 1 To Len( aList ) | |
nSum += aList[ nI ] | |
Next nI | |
Return nSum / Len( aList ) | |
Prelude Function Maximum( aList ) | |
Local nMax := aList[ 1 ] ; | |
, nI | |
For nI := 1 To Len( aList ) | |
If aList[ nI ] > nMax | |
nMax := aList[ nI ] | |
EndIf | |
Next nI | |
Return nMax | |
Prelude Function Minimum( aList ) | |
Local nMin := aList[ 1 ] ; | |
, nI | |
For nI := 1 To Len( aList ) | |
If aList[ nI ] < nMin | |
nMin := aList[ nI ] | |
EndIf | |
Next nI | |
Return nMin | |
Prelude Function Slice( nX, nY, aList ) | |
Local aAccum := { } ; | |
, nI | |
For nI := nX To nY | |
aAdd( aAccum, aList[ nI ] ) | |
Next nI | |
Return aAccum | |
Prelude Function Take( nX, aList ) | |
Local aAccum := Array( nX ) ; | |
, nI | |
For nI := 1 To nX | |
aAccum[ nI ] := aList[ nI ] | |
Next nI | |
Return aAccum | |
Prelude Function TakeWhile( bBlock, aList ) | |
Local aAccum := { } ; | |
, nI | |
For nI := 1 To Len( aList ) | |
If !Eval( bBlock, aList[ nI ] ) | |
Return aAccum | |
Else | |
aAdd( aAccum, aList[ nI ] ) | |
EndIf | |
Next nI | |
Return aAccum | |
Prelude Function Zip( aA, aB ) | |
Local aAccum := { } ; | |
, nI | |
For nI := 1 To Len( aA ) | |
aAdd( aAccum, { aA[ nI ], aB[ nI ] } ) | |
Next nI | |
Return aAccum | |
Prelude Function ZipWith( bBlock, aA, aB ) | |
Local aAccum := { } ; | |
, nI | |
For nI := 1 To Len( aA ) | |
aAdd( aAccum, Eval( bBlock, aA[ nI ], aB[ nI ] ) ) | |
Next nI | |
Return aAccum | |
Prelude Function ElemIndex( xElem, aList ) | |
Local nI | |
For nI := 1 To Len( aList ) | |
If aList[ nI ] == xElem | |
Return nI | |
EndIf | |
Next nI | |
Return Nil | |
Prelude Function ElemIndices( xElem, aList ) | |
Local aAccum := { } ; | |
, nI | |
For nI := 1 To Len( aList ) | |
If aList[ nI ] == xElem | |
aAdd( aAccum, nI ) | |
EndIf | |
Next nI | |
Return aAccum | |
Prelude Function FindIndex( bBlock, aList ) | |
Local nI | |
For nI := 1 To Len( aList ) | |
If Eval( bBlock, aList[ nI ] ) | |
Return nI | |
EndIf | |
Next nI | |
Return Nil | |
Prelude Function FindIndices( bBlock, aList ) | |
Local aAccum := { } ; | |
, nI | |
For nI := 1 To Len( aList ) | |
If Eval( bBlock, aList[ nI ] ) | |
aAdd( aAccum, nI ) | |
EndIf | |
Next nI | |
Return aAccum | |
Prelude Function Negate( nI ) | |
Return -( nI ) | |
Prelude Function SigNum( nI ) | |
If nI > 0 | |
Return 1 | |
ElseIf nI < 0 | |
Return -1 | |
EndIf | |
Return 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
First class blocks rule!