Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
osa1 committed Sep 16, 2012
0 parents commit 11a2204
Show file tree
Hide file tree
Showing 12 changed files with 308 additions and 0 deletions.
30 changes: 30 additions & 0 deletions LICENSE
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,30 @@
Copyright (c)2012, Ömer Sinan Ağacan

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.

* Neither the name of Ömer Sinan Ağacan nor the names of other
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2 changes: 2 additions & 0 deletions Setup.hs
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,2 @@
import Distribution.Simple
main = defaultMain
34 changes: 34 additions & 0 deletions language-lua.cabal
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,34 @@
-- language-lua.cabal auto-generated by cabal init. For additional
-- options, see
-- http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.html#pkg-descr.
-- The name of the package.
Name: language-lua

-- The package version. See the Haskell package versioning policy
-- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for
-- standards guiding when and how versions should be incremented.
Version: 0.1
Synopsis: Lua parser and pretty-printer
Homepage: http://github.com/osa1/language-lua
License: BSD3
License-file: LICENSE
Author: Ömer Sinan Ağacan
Maintainer: omeragacan@gmail.com
Category: Language
Build-type: Simple

-- Extra files to be distributed with the package, such as examples or
-- a README.
-- Extra-source-files:

-- Constraint on the version of Cabal needed to build this package.
Cabal-version: >=1.2

Library
-- Modules exported by the library.
Hs-source-dirs: src
Exposed-modules: Language.Lua.Expr, Language.Lua.Parser
Ghc-options: -O2
Build-depends: base >= 4,
mtl,
parsec
137 changes: 137 additions & 0 deletions src/Language/Lua/Lexer.x
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,137 @@
-- TODO:
-- * Multi-line comment and strings

{
module Language.Lua.Lexer where

import Language.Lua.Token
}

%wrapper "posn"

$space = [ \ \t ] -- horizontal white space
$eol = \n -- end of line

$letter = [a-zA-Z] -- first letter of variables
$identletter = [a-zA-Z_0-9] -- letters for rest of variables

$octdigit = 0-7 -- octal digits
$digit = 0-9 -- decimal digits
$hexdigit = [0-9a-fA-F] -- hexadecimal digits

$instr = \0-\255 # [ \\ \" \n ] -- valid character in a string literal
$anyButNL = \0-\255 # \n

@sp = $space*

-- escape characters
@charesc = \\ ([ntvbrfaeE\\\?\'\"] | $octdigit{1,3} | x$hexdigit+ | X$hexdigit+)

@digits = $digit+
@intpart = @digits
@fractpart = @digits

@mantpart = (@intpart? \. @fractpart) | @intpart \.
@exppart = [eE][\+\-]?@digits

@hexprefix = 0x | 0X
@hexdigits = $hexdigit+
@hexmant = @hexdigits? \. @hexdigits | @hexdigits\.


tokens :-

$white+ ;

$letter $identletter* { ident }

@hexprefix $hexdigit+ { \posn s -> (LTokNum s, posn) } -- FIXME
@mantpart @exppart? { \posn s -> (LTokNum s, posn) }
@digits { \posn s -> (LTokNum s, posn) }

\"($instr|@charesc)*\" { \posn s -> (LTokSLit s, posn) }

"+" { \posn _ -> (LTokPlus, posn) }
"-" { \posn _ -> (LTokMinus, posn) }
"*" { \posn _ -> (LTokStar, posn) }
"/" { \posn _ -> (LTokSlash, posn) }
"%" { \posn _ -> (LTokPercent, posn) }
"^" { \posn _ -> (LTokExp, posn) }
"#" { \posn _ -> (LTokSh, posn) }
"==" { \posn _ -> (LTokEqual, posn) }
"~=" { \posn _ -> (LTokNotequal, posn) }
"<=" { \posn _ -> (LTokLEq, posn) }
">=" { \posn _ -> (LTokGEq, posn) }
"<" { \posn _ -> (LTokLT, posn) }
">" { \posn _ -> (LTokGT, posn) }
"=" { \posn _ -> (LTokAssign, posn) }
"(" { \posn _ -> (LTokLParen, posn) }
")" { \posn _ -> (LTokRParen, posn) }
"{" { \posn _ -> (LTokLBrace, posn) }
"}" { \posn _ -> (LTokRBrace, posn) }
"[" { \posn _ -> (LTokLBracket, posn) }
"]" { \posn _ -> (LTokRBracket, posn) }
"::" { \posn _ -> (LTokDColon, posn) }
";" { \posn _ -> (LTokSemic, posn) }
":" { \posn _ -> (LTokColon, posn) }
"," { \posn _ -> (LTokComma, posn) }
"." { \posn _ -> (LTokDot, posn) }
".." { \posn _ -> (LTokDDot, posn) }
"..." { \posn _ -> (LTokEllipsis, posn) }


{

type TokPos = (LToken, AlexPosn)
type AlexAction = AlexPosn -> String -> TokPos

{-# INLINE ident #-}
ident :: AlexAction
ident posn "and" = (LTokAnd, posn)
ident posn "break" = (LTokBreak, posn)
ident posn "do" = (LTokDo, posn)
ident posn "else" = (LTokElse, posn)
ident posn "elseif" = (LTokElseIf, posn)
ident posn "end" = (LTokEnd, posn)
ident posn "false" = (LTokFalse, posn)
ident posn "for" = (LTokFor, posn)
ident posn "goto" = (LTokGoto, posn)
ident posn "if" = (LTokIf, posn)
ident posn "in" = (LTokIn, posn)
ident posn "local" = (LTokLocal, posn)
ident posn "nil" = (LTokNil, posn)
ident posn "not" = (LTokNot, posn)
ident posn "or" = (LTokOr, posn)
ident posn "repeat" = (LTokRepeat, posn)
ident posn "return" = (LTokReturn, posn)
ident posn "then" = (LTokThen, posn)
ident posn "true" = (LTokTrue, posn)
ident posn "until" = (LTokUntil, posn)
ident posn "while" = (LTokWhile, posn)
ident posn name = (LTokIdent name, posn)

--data AlexPosn = AlexPn !Int -- absolute character offset
-- !Int -- line number
-- !Int -- column number
--
--type AlexInput = (AlexPosn, -- current position,
-- Char, -- previous char
-- [Byte], -- rest of the bytes for the current char
-- String) -- current input string

--alexScanTokens :: String -> [token]
--alexScanTokens str = go (alexStartPos,'\n',[],str)
-- where go inp@(pos,_,_,str) =
-- case alexScan inp 0 of
-- AlexEOF -> []
-- AlexError ((AlexPn _ line column),_,_,_) -> error $ "lexical error at " ++ (show line) ++ " line, " ++ (show column) ++ " column"
-- AlexSkip inp' len -> go inp'
-- AlexToken inp' len act -> act pos (take len str) : go inp'


main = do
s <- getContents
print (alexScanTokens s)

}

28 changes: 28 additions & 0 deletions src/Language/Lua/Test.hs
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,28 @@
module Langauge.Lua.Test where

import Language.Lua.Lexer hiding (main)
import Data.List (sort)
import System.Directory (getDirectoryContents)
import System.FilePath (takeExtension, (</>), splitExtension)
import Control.Monad (forM)
import Test.HUnit

main :: IO ()
main = do
runLexerTests

runLexerTests :: IO ()
runLexerTests = do
files <- fmap (map ("tests" </>) . sort . filter luaFile) $ getDirectoryContents "tests"
tests <- forM files $ \file -> do
contents <- readFile file
let tokens = alexScanTokens contents
r <- readFile (fst $ splitExtension file)
return (file, TestCase $ assertEqual "lexer test" r (show tokens ++ "\n"))
let testList = TestList $ map (\(fileName, test) -> TestLabel fileName test) tests
putStrLn $ show testList
runTestTT testList
return ()

luaFile :: FilePath -> Bool
luaFile = (== ".lua") . takeExtension
62 changes: 62 additions & 0 deletions syntax
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,62 @@
chunk ::= block

block ::= {stat} [retstat]

stat ::= ‘;’ |
varlist ‘=’ explist |
functioncall |
label |
break |
goto Name |
do block end |
while exp do block end |
repeat block until exp |
if exp then block {elseif exp then block} [else block] end |
for Name ‘=’ exp ‘,’ exp [‘,’ exp] do block end |
for namelist in explist do block end |
function funcname funcbody |
local function Name funcbody |
local namelist [‘=’ explist]

retstat ::= return [explist] [‘;’]

label ::= ‘::’ Name ‘::’

funcname ::= Name {‘.’ Name} [‘:’ Name]

varlist ::= var {‘,’ var}

var ::= Name | prefixexp ‘[’ exp ‘]’ | prefixexp ‘.’ Name

namelist ::= Name {‘,’ Name}

explist ::= exp {‘,’ exp}

exp ::= nil | false | true | Number | String | ‘...’ | functiondef |
prefixexp | tableconstructor | exp binop exp | unop exp

prefixexp ::= var | functioncall | ‘(’ exp ‘)’

functioncall ::= prefixexp args | prefixexp ‘:’ Name args

args ::= ‘(’ [explist] ‘)’ | tableconstructor | String

functiondef ::= function funcbody

funcbody ::= ‘(’ [parlist] ‘)’ block end

parlist ::= namelist [‘,’ ‘...’] | ‘...’

tableconstructor ::= ‘{’ [fieldlist] ‘}’

fieldlist ::= field {fieldsep field} [fieldsep]

field ::= ‘[’ exp ‘]’ ‘=’ exp | Name ‘=’ exp | exp

fieldsep ::= ‘,’ | ‘;’

binop ::= ‘+’ | ‘-’ | ‘*’ | ‘/’ | ‘^’ | ‘%’ | ‘..’ |
‘<’ | ‘<=’ | ‘>’ | ‘>=’ | ‘==’ | ‘~=’ |
and | or

unop ::= ‘-’ | not | ‘#’
1 change: 1 addition & 0 deletions tests/numbers
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1 @@
[LTokNum "3",LTokNum "3.0",LTokNum "3.1416",LTokNum "314.16e-2",LTokNum "0.31416E1",LTokNum "0xff",LTokNum "0x0.1E",LTokNum "0xA23p-4",LTokNum "0X1.921FB54442D18P+1"]
9 changes: 9 additions & 0 deletions tests/numbers.lua
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,9 @@
3
3.0
3.1416
314.16e-2
0.31416E1
0xff
0x0.1E
0xA23p-4
0X1.921FB54442D18P+1
1 change: 1 addition & 0 deletions tests/test
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1 @@
[(LTokNum "1",AlexPn 0 1 1),(LTokIdent "bir",AlexPn 2 2 1),(LTokMinus,AlexPn 5 2 4),(LTokIdent "token",AlexPn 6 2 5),(LTokSLit "\"bir string\"",AlexPn 12 3 1)]
3 changes: 3 additions & 0 deletions tests/test.lua
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,3 @@
1
bir-token
"bir string"
1 change: 1 addition & 0 deletions tests/test2
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1 @@
[]
Empty file added tests/test2.lua
Empty file.

0 comments on commit 11a2204

Please sign in to comment.