Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
C
capnproto
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
capnproto
Commits
f0877237
Commit
f0877237
authored
Feb 16, 2013
by
Kenton Varda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Bunch of little things.
parent
2e3f671c
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
235 additions
and
50 deletions
+235
-50
capnproto-compiler.cabal
compiler/capnproto-compiler.cabal
+2
-1
Compiler.hs
compiler/src/Compiler.hs
+89
-19
Grammar.hs
compiler/src/Grammar.hs
+14
-2
Lexer.hs
compiler/src/Lexer.hs
+1
-0
Main.hs
compiler/src/Main.hs
+23
-2
Parser.hs
compiler/src/Parser.hs
+57
-22
Semantics.hs
compiler/src/Semantics.hs
+11
-3
Token.hs
compiler/src/Token.hs
+8
-1
Util.hs
compiler/src/Util.hs
+30
-0
No files found.
compiler/capnproto-compiler.cabal
View file @
f0877237
...
@@ -19,5 +19,6 @@ executable capnproto-compiler
...
@@ -19,5 +19,6 @@ executable capnproto-compiler
Grammar,
Grammar,
Parser,
Parser,
Compiler,
Compiler,
Semantics
Semantics,
Util
compiler/src/Compiler.hs
View file @
f0877237
...
@@ -28,6 +28,8 @@ import Semantics
...
@@ -28,6 +28,8 @@ import Semantics
import
Token
(
Located
(
Located
))
import
Token
(
Located
(
Located
))
import
Parser
(
parseFile
)
import
Parser
(
parseFile
)
import
qualified
Data.Map
as
Map
import
qualified
Data.Map
as
Map
import
qualified
Data.List
as
List
import
Data.Maybe
(
mapMaybe
)
import
Text.Parsec.Pos
(
SourcePos
,
newPos
)
import
Text.Parsec.Pos
(
SourcePos
,
newPos
)
import
Text.Parsec.Error
(
ParseError
,
newErrorMessage
,
Message
(
Message
,
Expect
))
import
Text.Parsec.Error
(
ParseError
,
newErrorMessage
,
Message
(
Message
,
Expect
))
import
Text.Printf
(
printf
)
import
Text.Printf
(
printf
)
...
@@ -98,6 +100,8 @@ feedback f = status where
...
@@ -98,6 +100,8 @@ feedback f = status where
statusToMaybe
(
Active
x
_
)
=
Just
x
statusToMaybe
(
Active
x
_
)
=
Just
x
statusToMaybe
(
Failed
_
)
=
Nothing
statusToMaybe
(
Failed
_
)
=
Nothing
doAll
statuses
=
Active
[
x
|
(
Active
x
_
)
<-
statuses
]
(
concatMap
statusErrors
statuses
)
------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------
-- Symbol lookup
-- Symbol lookup
------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------
...
@@ -150,30 +154,48 @@ builtinTypeMap = Map.fromList
...
@@ -150,30 +154,48 @@ builtinTypeMap = Map.fromList
------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------
fromIntegerChecked
::
Integral
a
=>
SourcePos
->
Integer
->
Status
a
fromIntegerChecked
::
Integral
a
=>
S
tring
->
S
ourcePos
->
Integer
->
Status
a
fromIntegerChecked
pos
x
=
result
where
fromIntegerChecked
name
pos
x
=
result
where
unchecked
=
fromInteger
x
unchecked
=
fromInteger
x
result
=
if
toInteger
unchecked
==
x
result
=
if
toInteger
unchecked
==
x
then
succeed
unchecked
then
succeed
unchecked
else
makeError
pos
"Integer out of range for type."
else
makeError
pos
(
printf
"Integer %d out of range for type %s."
x
name
)
compileValue
::
SourcePos
->
TypeDesc
->
FieldValue
->
Status
ValueDesc
compileValue
_
(
BuiltinType
BuiltinVoid
)
VoidFieldValue
=
succeed
VoidDesc
compileValue
_
(
BuiltinType
BuiltinVoid
)
VoidFieldValue
=
succeed
VoidDesc
compileValue
_
(
BuiltinType
BuiltinBool
)
(
BoolFieldValue
x
)
=
succeed
(
BoolDesc
x
)
compileValue
_
(
BuiltinType
BuiltinBool
)
(
BoolFieldValue
x
)
=
succeed
(
BoolDesc
x
)
compileValue
pos
(
BuiltinType
BuiltinInt8
)
(
IntegerFieldValue
x
)
=
fmap
Int8Desc
(
fromIntegerChecked
pos
x
)
compileValue
pos
(
BuiltinType
BuiltinInt8
)
(
IntegerFieldValue
x
)
=
fmap
Int8Desc
(
fromIntegerChecked
"Int8"
pos
x
)
compileValue
pos
(
BuiltinType
BuiltinInt16
)
(
IntegerFieldValue
x
)
=
fmap
Int16Desc
(
fromIntegerChecked
pos
x
)
compileValue
pos
(
BuiltinType
BuiltinInt16
)
(
IntegerFieldValue
x
)
=
fmap
Int16Desc
(
fromIntegerChecked
"Int16"
pos
x
)
compileValue
pos
(
BuiltinType
BuiltinInt32
)
(
IntegerFieldValue
x
)
=
fmap
Int32Desc
(
fromIntegerChecked
pos
x
)
compileValue
pos
(
BuiltinType
BuiltinInt32
)
(
IntegerFieldValue
x
)
=
fmap
Int32Desc
(
fromIntegerChecked
"Int32"
pos
x
)
compileValue
pos
(
BuiltinType
BuiltinInt64
)
(
IntegerFieldValue
x
)
=
fmap
Int64Desc
(
fromIntegerChecked
pos
x
)
compileValue
pos
(
BuiltinType
BuiltinInt64
)
(
IntegerFieldValue
x
)
=
fmap
Int64Desc
(
fromIntegerChecked
"Int64"
pos
x
)
compileValue
pos
(
BuiltinType
BuiltinUInt8
)
(
IntegerFieldValue
x
)
=
fmap
UInt8Desc
(
fromIntegerChecked
pos
x
)
compileValue
pos
(
BuiltinType
BuiltinUInt8
)
(
IntegerFieldValue
x
)
=
fmap
UInt8Desc
(
fromIntegerChecked
"UInt8"
pos
x
)
compileValue
pos
(
BuiltinType
BuiltinUInt16
)
(
IntegerFieldValue
x
)
=
fmap
UInt16Desc
(
fromIntegerChecked
pos
x
)
compileValue
pos
(
BuiltinType
BuiltinUInt16
)
(
IntegerFieldValue
x
)
=
fmap
UInt16Desc
(
fromIntegerChecked
"UInt16"
pos
x
)
compileValue
pos
(
BuiltinType
BuiltinUInt32
)
(
IntegerFieldValue
x
)
=
fmap
UInt32Desc
(
fromIntegerChecked
pos
x
)
compileValue
pos
(
BuiltinType
BuiltinUInt32
)
(
IntegerFieldValue
x
)
=
fmap
UInt32Desc
(
fromIntegerChecked
"UInt32"
pos
x
)
compileValue
pos
(
BuiltinType
BuiltinUInt64
)
(
IntegerFieldValue
x
)
=
fmap
UInt64Desc
(
fromIntegerChecked
pos
x
)
compileValue
pos
(
BuiltinType
BuiltinUInt64
)
(
IntegerFieldValue
x
)
=
fmap
UInt64Desc
(
fromIntegerChecked
"UInt64"
pos
x
)
compileValue
_
(
BuiltinType
BuiltinFloat32
)
(
FloatFieldValue
x
)
=
succeed
(
Float32Desc
(
realToFrac
x
))
compileValue
_
(
BuiltinType
BuiltinFloat32
)
(
FloatFieldValue
x
)
=
succeed
(
Float32Desc
(
realToFrac
x
))
compileValue
_
(
BuiltinType
BuiltinFloat64
)
(
FloatFieldValue
x
)
=
succeed
(
Float64Desc
x
)
compileValue
_
(
BuiltinType
BuiltinFloat64
)
(
FloatFieldValue
x
)
=
succeed
(
Float64Desc
x
)
compileValue
_
(
BuiltinType
BuiltinFloat32
)
(
IntegerFieldValue
x
)
=
succeed
(
Float32Desc
(
realToFrac
x
))
compileValue
_
(
BuiltinType
BuiltinFloat32
)
(
IntegerFieldValue
x
)
=
succeed
(
Float32Desc
(
realToFrac
x
))
compileValue
_
(
BuiltinType
BuiltinFloat64
)
(
IntegerFieldValue
x
)
=
succeed
(
Float64Desc
(
realToFrac
x
))
compileValue
_
(
BuiltinType
BuiltinFloat64
)
(
IntegerFieldValue
x
)
=
succeed
(
Float64Desc
(
realToFrac
x
))
compileValue
_
(
BuiltinType
BuiltinText
)
(
StringFieldValue
x
)
=
succeed
(
TextDesc
x
)
compileValue
_
(
BuiltinType
BuiltinText
)
(
StringFieldValue
x
)
=
succeed
(
TextDesc
x
)
compileValue
_
(
BuiltinType
BuiltinBytes
)
(
StringFieldValue
x
)
=
compileValue
_
(
BuiltinType
BuiltinData
)
(
StringFieldValue
x
)
=
succeed
(
BytesDesc
(
map
(
fromIntegral
.
fromEnum
)
x
))
succeed
(
DataDesc
(
map
(
fromIntegral
.
fromEnum
)
x
))
compileValue
pos
(
EnumType
desc
)
(
IdentifierFieldValue
name
)
=
case
lookupMember
name
(
enumMemberMap
desc
)
of
Just
(
DescEnumValue
value
)
->
succeed
(
EnumValueValueDesc
value
)
_
->
makeError
pos
(
printf
"Enum type %s has no value %s."
(
enumName
desc
)
name
)
compileValue
_
(
StructType
desc
)
(
RecordFieldValue
fields
)
=
result
where
result
=
fmap
StructValueDesc
(
doAll
(
map
compileFieldAssignment
fields
))
compileFieldAssignment
::
(
Located
String
,
Located
FieldValue
)
->
Status
(
FieldDesc
,
ValueDesc
)
compileFieldAssignment
(
Located
namePos
name
,
Located
valPos
val
)
=
case
lookupMember
name
(
structMemberMap
desc
)
of
Just
(
DescField
field
)
->
fmap
(
\
x
->
(
field
,
x
))
(
compileValue
valPos
(
fieldType
field
)
val
)
_
->
makeError
namePos
(
printf
"Struct %s has no field %s."
(
structName
desc
)
name
)
compileValue
_
(
ListType
t
)
(
ListFieldValue
l
)
=
fmap
ListDesc
(
doAll
[
compileValue
vpos
t
v
|
Located
vpos
v
<-
l
])
compileValue
pos
(
BuiltinType
BuiltinVoid
)
_
=
makeError
pos
"Void fields cannot have values."
compileValue
pos
(
BuiltinType
BuiltinVoid
)
_
=
makeError
pos
"Void fields cannot have values."
compileValue
pos
(
BuiltinType
BuiltinBool
)
_
=
makeExpectError
pos
"boolean"
compileValue
pos
(
BuiltinType
BuiltinBool
)
_
=
makeExpectError
pos
"boolean"
...
@@ -188,12 +210,12 @@ compileValue pos (BuiltinType BuiltinUInt64) _ = makeExpectError pos "integer"
...
@@ -188,12 +210,12 @@ compileValue pos (BuiltinType BuiltinUInt64) _ = makeExpectError pos "integer"
compileValue
pos
(
BuiltinType
BuiltinFloat32
)
_
=
makeExpectError
pos
"number"
compileValue
pos
(
BuiltinType
BuiltinFloat32
)
_
=
makeExpectError
pos
"number"
compileValue
pos
(
BuiltinType
BuiltinFloat64
)
_
=
makeExpectError
pos
"number"
compileValue
pos
(
BuiltinType
BuiltinFloat64
)
_
=
makeExpectError
pos
"number"
compileValue
pos
(
BuiltinType
BuiltinText
)
_
=
makeExpectError
pos
"string"
compileValue
pos
(
BuiltinType
BuiltinText
)
_
=
makeExpectError
pos
"string"
compileValue
pos
(
BuiltinType
Builtin
Bytes
)
_
=
makeExpectError
pos
"string"
compileValue
pos
(
BuiltinType
Builtin
Data
)
_
=
makeExpectError
pos
"string"
compileValue
pos
(
EnumType
_
)
_
=
makeE
rror
pos
"Unimplemented: enum default values
"
compileValue
pos
(
EnumType
_
)
_
=
makeE
xpectError
pos
"enum value name
"
compileValue
pos
(
StructType
_
)
_
=
makeE
rror
pos
"Unimplemented: struct default value
s"
compileValue
pos
(
StructType
_
)
_
=
makeE
xpectError
pos
"parenthesized list of field assignment
s"
compileValue
pos
(
InterfaceType
_
)
_
=
makeError
pos
"Interfaces can't have default values."
compileValue
pos
(
InterfaceType
_
)
_
=
makeError
pos
"Interfaces can't have default values."
compileValue
pos
(
ListType
_
)
_
=
makeE
rror
pos
"Unimplemented: array default values
"
compileValue
pos
(
ListType
_
)
_
=
makeE
xpectError
pos
"list
"
makeFileMemberMap
::
FileDesc
->
Map
.
Map
String
Desc
makeFileMemberMap
::
FileDesc
->
Map
.
Map
String
Desc
makeFileMemberMap
desc
=
Map
.
fromList
allMembers
where
makeFileMemberMap
desc
=
Map
.
fromList
allMembers
where
...
@@ -226,6 +248,47 @@ compileType scope (TypeExpression n (param:moreParams)) = do
...
@@ -226,6 +248,47 @@ compileType scope (TypeExpression n (param:moreParams)) = do
else
makeError
(
declNamePos
n
)
"'List' requires exactly one type parameter."
else
makeError
(
declNamePos
n
)
"'List' requires exactly one type parameter."
_
->
makeError
(
declNamePos
n
)
"Only the type 'List' can have type parameters."
_
->
makeError
(
declNamePos
n
)
"Only the type 'List' can have type parameters."
------------------------------------------------------------------------------------------
requireSequentialNumbering
::
String
->
[
Located
Integer
]
->
Status
()
requireSequentialNumbering
kind
items
=
Active
()
(
loop
0
sortedItems
)
where
sortedItems
=
List
.
sort
items
loop
_
[]
=
[]
loop
expected
(
Located
pos
num
:
rest
)
=
result
where
rest'
=
loop
(
num
+
1
)
rest
result
=
if
num
==
expected
then
rest'
else
err
:
rest'
where
err
=
newErrorMessage
(
Message
message
)
pos
message
=
printf
"Skipped number %d. %s must be numbered sequentially starting
\
\
from zero."
expected
kind
maxFieldNumber
=
1023
requireFieldNumbersInRange
fieldNums
=
Active
()
[
fieldNumError
num
pos
|
Located
pos
num
<-
fieldNums
,
num
>
maxFieldNumber
]
where
fieldNumError
num
=
newErrorMessage
(
Message
(
printf
"Field number %d too large; maximum is %d."
num
maxFieldNumber
))
requireNoDuplicateNames
::
[
Declaration
]
->
Status
()
requireNoDuplicateNames
decls
=
Active
()
(
loop
(
List
.
sort
locatedNames
))
where
locatedNames
=
mapMaybe
declarationName
decls
loop
(
Located
pos1
val1
:
Located
pos2
val2
:
t
)
=
if
val1
==
val2
then
dupError
val1
pos1
:
dupError
val2
pos2
:
loop2
val1
t
else
loop
t
loop
_
=
[]
loop2
val1
l
@
(
Located
pos2
val2
:
t
)
=
if
val1
==
val2
then
dupError
val2
pos2
:
loop2
val1
t
else
loop
l
loop2
_
_
=
[]
dupError
val
=
newErrorMessage
(
Message
message
)
where
message
=
printf
"Duplicate declaration
\"
%s
\"
."
val
------------------------------------------------------------------------------------------
data
CompiledDecl
=
CompiledMember
String
(
Status
Desc
)
data
CompiledDecl
=
CompiledMember
String
(
Status
Desc
)
|
CompiledOption
(
Status
OptionAssignmentDesc
)
|
CompiledOption
(
Status
OptionAssignmentDesc
)
...
@@ -242,8 +305,6 @@ compileChildDecls desc decls = Active (members, memberMap, options) errors where
...
@@ -242,8 +305,6 @@ compileChildDecls desc decls = Active (members, memberMap, options) errors where
|
CompiledOption
(
Active
o
_
)
<-
compiledDecls
]
|
CompiledOption
(
Active
o
_
)
<-
compiledDecls
]
errors
=
concatMap
compiledErrors
compiledDecls
errors
=
concatMap
compiledErrors
compiledDecls
doAll
statuses
=
Active
[
x
|
(
Active
x
_
)
<-
statuses
]
(
concatMap
statusErrors
statuses
)
compileDecl
scope
(
AliasDecl
(
Located
_
name
)
target
)
=
compileDecl
scope
(
AliasDecl
(
Located
_
name
)
target
)
=
CompiledMember
name
(
do
CompiledMember
name
(
do
targetDesc
<-
lookupDesc
scope
target
targetDesc
<-
lookupDesc
scope
target
...
@@ -267,6 +328,8 @@ compileDecl scope (ConstantDecl (Located _ name) t (Located valuePos value)) =
...
@@ -267,6 +328,8 @@ compileDecl scope (ConstantDecl (Located _ name) t (Located valuePos value)) =
compileDecl
scope
(
EnumDecl
(
Located
_
name
)
decls
)
=
compileDecl
scope
(
EnumDecl
(
Located
_
name
)
decls
)
=
CompiledMember
name
(
feedback
(
\
desc
->
do
CompiledMember
name
(
feedback
(
\
desc
->
do
(
members
,
memberMap
,
options
)
<-
compileChildDecls
desc
decls
(
members
,
memberMap
,
options
)
<-
compileChildDecls
desc
decls
requireNoDuplicateNames
decls
requireSequentialNumbering
"Enum values"
[
num
|
EnumValueDecl
_
num
_
<-
decls
]
return
(
DescEnum
EnumDesc
return
(
DescEnum
EnumDesc
{
enumName
=
name
{
enumName
=
name
,
enumParent
=
scope
,
enumParent
=
scope
...
@@ -289,6 +352,10 @@ compileDecl scope (EnumValueDecl (Located _ name) (Located _ number) decls) =
...
@@ -289,6 +352,10 @@ compileDecl scope (EnumValueDecl (Located _ name) (Located _ number) decls) =
compileDecl
scope
(
StructDecl
(
Located
_
name
)
decls
)
=
compileDecl
scope
(
StructDecl
(
Located
_
name
)
decls
)
=
CompiledMember
name
(
feedback
(
\
desc
->
do
CompiledMember
name
(
feedback
(
\
desc
->
do
(
members
,
memberMap
,
options
)
<-
compileChildDecls
desc
decls
(
members
,
memberMap
,
options
)
<-
compileChildDecls
desc
decls
requireNoDuplicateNames
decls
fieldNums
<-
return
[
num
|
FieldDecl
_
num
_
_
_
<-
decls
]
requireSequentialNumbering
"Fields"
fieldNums
requireFieldNumbersInRange
fieldNums
return
(
DescStruct
StructDesc
return
(
DescStruct
StructDesc
{
structName
=
name
{
structName
=
name
,
structParent
=
scope
,
structParent
=
scope
...
@@ -322,6 +389,8 @@ compileDecl scope (FieldDecl (Located _ name) (Located _ number) typeExp default
...
@@ -322,6 +389,8 @@ compileDecl scope (FieldDecl (Located _ name) (Located _ number) typeExp default
compileDecl
scope
(
InterfaceDecl
(
Located
_
name
)
decls
)
=
compileDecl
scope
(
InterfaceDecl
(
Located
_
name
)
decls
)
=
CompiledMember
name
(
feedback
(
\
desc
->
do
CompiledMember
name
(
feedback
(
\
desc
->
do
(
members
,
memberMap
,
options
)
<-
compileChildDecls
desc
decls
(
members
,
memberMap
,
options
)
<-
compileChildDecls
desc
decls
requireNoDuplicateNames
decls
requireSequentialNumbering
"Methods"
[
num
|
MethodDecl
_
num
_
_
_
<-
decls
]
return
(
DescInterface
InterfaceDesc
return
(
DescInterface
InterfaceDesc
{
interfaceName
=
name
{
interfaceName
=
name
,
interfaceParent
=
scope
,
interfaceParent
=
scope
...
@@ -372,6 +441,7 @@ compileParam scope (name, typeExp, defaultValue) = do
...
@@ -372,6 +441,7 @@ compileParam scope (name, typeExp, defaultValue) = do
compileFile
name
decls
=
compileFile
name
decls
=
feedback
(
\
desc
->
do
feedback
(
\
desc
->
do
(
members
,
memberMap
,
options
)
<-
compileChildDecls
(
DescFile
desc
)
decls
(
members
,
memberMap
,
options
)
<-
compileChildDecls
(
DescFile
desc
)
decls
requireNoDuplicateNames
decls
return
FileDesc
return
FileDesc
{
fileName
=
name
{
fileName
=
name
,
fileImports
=
[]
,
fileImports
=
[]
...
...
compiler/src/Grammar.hs
View file @
f0877237
...
@@ -39,8 +39,9 @@ data FieldValue = VoidFieldValue
...
@@ -39,8 +39,9 @@ data FieldValue = VoidFieldValue
|
IntegerFieldValue
Integer
|
IntegerFieldValue
Integer
|
FloatFieldValue
Double
|
FloatFieldValue
Double
|
StringFieldValue
String
|
StringFieldValue
String
|
ArrayFieldValue
[
FieldValue
]
|
IdentifierFieldValue
String
|
RecordFieldValue
[(
String
,
FieldValue
)]
|
ListFieldValue
[
Located
FieldValue
]
|
RecordFieldValue
[(
Located
String
,
Located
FieldValue
)]
deriving
(
Show
)
deriving
(
Show
)
data
Declaration
=
AliasDecl
(
Located
String
)
DeclName
data
Declaration
=
AliasDecl
(
Located
String
)
DeclName
...
@@ -56,3 +57,14 @@ data Declaration = AliasDecl (Located String) DeclName
...
@@ -56,3 +57,14 @@ data Declaration = AliasDecl (Located String) DeclName
TypeExpression
[
Declaration
]
TypeExpression
[
Declaration
]
|
OptionDecl
DeclName
(
Located
FieldValue
)
|
OptionDecl
DeclName
(
Located
FieldValue
)
deriving
(
Show
)
deriving
(
Show
)
declarationName
::
Declaration
->
Maybe
(
Located
String
)
declarationName
(
AliasDecl
n
_
)
=
Just
n
declarationName
(
ConstantDecl
n
_
_
)
=
Just
n
declarationName
(
EnumDecl
n
_
)
=
Just
n
declarationName
(
EnumValueDecl
n
_
_
)
=
Just
n
declarationName
(
StructDecl
n
_
)
=
Just
n
declarationName
(
FieldDecl
n
_
_
_
_
)
=
Just
n
declarationName
(
InterfaceDecl
n
_
)
=
Just
n
declarationName
(
MethodDecl
n
_
_
_
_
)
=
Just
n
declarationName
(
OptionDecl
_
_
)
=
Nothing
compiler/src/Lexer.hs
View file @
f0877237
...
@@ -86,6 +86,7 @@ token = keyword
...
@@ -86,6 +86,7 @@ token = keyword
<|>
liftM
(
const
Colon
)
(
symbol
":"
)
<|>
liftM
(
const
Colon
)
(
symbol
":"
)
<|>
liftM
(
const
Period
)
(
symbol
"."
)
<|>
liftM
(
const
Period
)
(
symbol
"."
)
<|>
liftM
(
const
EqualsSign
)
(
symbol
"="
)
<|>
liftM
(
const
EqualsSign
)
(
symbol
"="
)
<|>
liftM
(
const
MinusSign
)
(
symbol
"-"
)
<?>
"token"
<?>
"token"
locatedToken
=
located
token
locatedToken
=
located
token
...
...
compiler/src/Main.hs
View file @
f0877237
...
@@ -25,6 +25,10 @@ module Main ( main ) where
...
@@ -25,6 +25,10 @@ module Main ( main ) where
import
System.Environment
import
System.Environment
import
Compiler
import
Compiler
import
Util
(
delimit
)
import
Text.Parsec.Pos
import
Text.Parsec.Error
import
Text.Printf
(
printf
)
main
::
IO
()
main
::
IO
()
main
=
do
main
=
do
...
@@ -35,5 +39,22 @@ handleFile filename = do
...
@@ -35,5 +39,22 @@ handleFile filename = do
text
<-
readFile
filename
text
<-
readFile
filename
case
parseAndCompileFile
filename
text
of
case
parseAndCompileFile
filename
text
of
Active
desc
[]
->
print
desc
Active
desc
[]
->
print
desc
Active
_
e
->
mapM_
print
e
Active
_
e
->
mapM_
printError
e
Failed
e
->
mapM_
print
e
Failed
e
->
mapM_
printError
e
--printError e = mapM_ printMessage (errorMessages e) where
-- pos = errorPos e
-- f = sourceName pos
-- l = sourceLine pos
-- c = sourceColumn pos
-- printMessage :: Message -> IO ()
-- printMessage m = printf "%s:%d:%d: %s\n" f l c (messageString m)
printError
e
=
printf
"%s:%d:%d: %s
\n
"
f
l
c
m'
where
pos
=
errorPos
e
f
=
sourceName
pos
l
=
sourceLine
pos
c
=
sourceColumn
pos
m
=
showErrorMessages
"or"
"Unknown parse error"
"Expected"
"Unexpected"
"end of expression"
(
errorMessages
e
)
m'
=
delimit
"; "
(
lines
m
)
compiler/src/Parser.hs
View file @
f0877237
...
@@ -25,12 +25,31 @@ module Parser (parseFile) where
...
@@ -25,12 +25,31 @@ module Parser (parseFile) where
import
Text.Parsec
hiding
(
tokens
)
import
Text.Parsec
hiding
(
tokens
)
import
Token
import
Token
import
Control.Monad
(
liftM
)
import
Grammar
import
Grammar
import
Lexer
(
lexer
)
import
Lexer
(
lexer
)
import
Control.Monad.Identity
tokenParser
::
(
Located
Token
->
Maybe
a
)
->
Parsec
[
Located
Token
]
u
a
tokenParser
::
(
Located
Token
->
Maybe
a
)
->
Parsec
[
Located
Token
]
u
a
tokenParser
=
token
(
show
.
locatedValue
)
locatedPos
tokenParser
=
token
(
tokenErrorString
.
locatedValue
)
locatedPos
tokenErrorString
(
Identifier
s
)
=
"identifier
\"
"
++
s
++
"
\"
"
tokenErrorString
(
ParenthesizedList
_
)
=
"parenthesized list"
tokenErrorString
(
BracketedList
_
)
=
"bracketed list"
tokenErrorString
(
LiteralInt
i
)
=
"integer literal "
++
show
i
tokenErrorString
(
LiteralFloat
f
)
=
"float literal "
++
show
f
tokenErrorString
(
LiteralString
s
)
=
"string literal "
++
show
s
tokenErrorString
AtSign
=
"
\"
@
\"
"
tokenErrorString
Colon
=
"
\"
:
\"
"
tokenErrorString
Period
=
"
\"
.
\"
"
tokenErrorString
EqualsSign
=
"
\"
=
\"
"
tokenErrorString
MinusSign
=
"
\"
-
\"
"
tokenErrorString
ImportKeyword
=
"
\"
import
\"
"
tokenErrorString
UsingKeyword
=
"
\"
using
\"
"
tokenErrorString
ConstKeyword
=
"
\"
const
\"
"
tokenErrorString
EnumKeyword
=
"
\"
enum
\"
"
tokenErrorString
StructKeyword
=
"
\"
struct
\"
"
tokenErrorString
InterfaceKeyword
=
"
\"
interface
\"
"
tokenErrorString
OptionKeyword
=
"
\"
option
\"
"
type
TokenParser
=
Parsec
[
Located
Token
]
[
ParseError
]
type
TokenParser
=
Parsec
[
Located
Token
]
[
ParseError
]
...
@@ -49,22 +68,23 @@ matchLiteralFloat t = case locatedValue t of { (LiteralFloat v) -> Jus
...
@@ -49,22 +68,23 @@ matchLiteralFloat t = case locatedValue t of { (LiteralFloat v) -> Jus
matchLiteralString
t
=
case
locatedValue
t
of
{
(
LiteralString
v
)
->
Just
v
;
_
->
Nothing
}
matchLiteralString
t
=
case
locatedValue
t
of
{
(
LiteralString
v
)
->
Just
v
;
_
->
Nothing
}
matchSimpleToken
expected
t
=
if
locatedValue
t
==
expected
then
Just
()
else
Nothing
matchSimpleToken
expected
t
=
if
locatedValue
t
==
expected
then
Just
()
else
Nothing
identifier
=
tokenParser
matchIdentifier
identifier
=
tokenParser
matchIdentifier
<?>
"identifier"
literalInt
=
tokenParser
matchLiteralInt
literalInt
=
tokenParser
matchLiteralInt
<?>
"integer"
literalFloat
=
tokenParser
matchLiteralFloat
literalFloat
=
tokenParser
matchLiteralFloat
<?>
"floating-point number"
literalString
=
tokenParser
matchLiteralString
literalString
=
tokenParser
matchLiteralString
<?>
"string"
atSign
=
tokenParser
(
matchSimpleToken
AtSign
)
atSign
=
tokenParser
(
matchSimpleToken
AtSign
)
<?>
"
\"
@
\"
"
colon
=
tokenParser
(
matchSimpleToken
Colon
)
colon
=
tokenParser
(
matchSimpleToken
Colon
)
<?>
"
\"
:
\"
"
period
=
tokenParser
(
matchSimpleToken
Period
)
period
=
tokenParser
(
matchSimpleToken
Period
)
<?>
"
\"
.
\"
"
equalsSign
=
tokenParser
(
matchSimpleToken
EqualsSign
)
equalsSign
=
tokenParser
(
matchSimpleToken
EqualsSign
)
<?>
"
\"
=
\"
"
importKeyword
=
tokenParser
(
matchSimpleToken
ImportKeyword
)
minusSign
=
tokenParser
(
matchSimpleToken
MinusSign
)
<?>
"
\"
=
\"
"
usingKeyword
=
tokenParser
(
matchSimpleToken
UsingKeyword
)
importKeyword
=
tokenParser
(
matchSimpleToken
ImportKeyword
)
<?>
"
\"
import
\"
"
constKeyword
=
tokenParser
(
matchSimpleToken
ConstKeyword
)
usingKeyword
=
tokenParser
(
matchSimpleToken
UsingKeyword
)
<?>
"
\"
using
\"
"
enumKeyword
=
tokenParser
(
matchSimpleToken
EnumKeyword
)
constKeyword
=
tokenParser
(
matchSimpleToken
ConstKeyword
)
<?>
"
\"
const
\"
"
structKeyword
=
tokenParser
(
matchSimpleToken
StructKeyword
)
enumKeyword
=
tokenParser
(
matchSimpleToken
EnumKeyword
)
<?>
"
\"
enum
\"
"
interfaceKeyword
=
tokenParser
(
matchSimpleToken
InterfaceKeyword
)
structKeyword
=
tokenParser
(
matchSimpleToken
StructKeyword
)
<?>
"
\"
struct
\"
"
optionKeyword
=
tokenParser
(
matchSimpleToken
OptionKeyword
)
interfaceKeyword
=
tokenParser
(
matchSimpleToken
InterfaceKeyword
)
<?>
"
\"
interface
\"
"
optionKeyword
=
tokenParser
(
matchSimpleToken
OptionKeyword
)
<?>
"
\"
option
\"
"
parenthesizedList
parser
=
do
parenthesizedList
parser
=
do
items
<-
tokenParser
matchParenthesizedList
items
<-
tokenParser
matchParenthesizedList
...
@@ -155,16 +175,22 @@ fieldDecl statements = do
...
@@ -155,16 +175,22 @@ fieldDecl statements = do
children
<-
parseBlock
fieldLine
statements
children
<-
parseBlock
fieldLine
statements
return
(
FieldDecl
name
ordinal
t
value
children
)
return
(
FieldDecl
name
ordinal
t
value
children
)
negativeFieldValue
=
liftM
(
IntegerFieldValue
.
negate
)
literalInt
<|>
liftM
(
FloatFieldValue
.
negate
)
literalFloat
fieldValue
=
liftM
IntegerFieldValue
literalInt
fieldValue
=
liftM
IntegerFieldValue
literalInt
<|>
liftM
FloatFieldValue
literalFloat
<|>
liftM
FloatFieldValue
literalFloat
<|>
liftM
StringFieldValue
literalString
<|>
liftM
StringFieldValue
literalString
<|>
liftM
ArrayFieldValue
(
bracketedList
fieldValue
)
<|>
liftM
IdentifierFieldValue
identifier
<|>
liftM
ListFieldValue
(
bracketedList
(
located
fieldValue
))
<|>
liftM
RecordFieldValue
(
parenthesizedList
fieldAssignment
)
<|>
liftM
RecordFieldValue
(
parenthesizedList
fieldAssignment
)
<|>
(
minusSign
>>
negativeFieldValue
)
<?>
"default value"
fieldAssignment
=
do
fieldAssignment
=
do
name
<-
identifier
name
<-
located
identifier
equalsSign
equalsSign
value
<-
fieldValue
value
<-
located
fieldValue
return
(
name
,
value
)
return
(
name
,
value
)
fieldLine
::
Maybe
[
Located
Statement
]
->
TokenParser
Declaration
fieldLine
::
Maybe
[
Located
Statement
]
->
TokenParser
Declaration
...
@@ -186,6 +212,7 @@ methodDecl statements = do
...
@@ -186,6 +212,7 @@ methodDecl statements = do
atSign
atSign
ordinal
<-
located
literalInt
ordinal
<-
located
literalInt
params
<-
parenthesizedList
paramDecl
params
<-
parenthesizedList
paramDecl
colon
t
<-
typeExpression
t
<-
typeExpression
children
<-
parseBlock
methodLine
statements
children
<-
parseBlock
methodLine
statements
return
(
MethodDecl
name
ordinal
params
t
children
)
return
(
MethodDecl
name
ordinal
params
t
children
)
...
@@ -227,8 +254,16 @@ parseBlock parser statements = finish where
...
@@ -227,8 +254,16 @@ parseBlock parser statements = finish where
return
[
result
|
Right
(
result
,
_
)
<-
results
]
return
[
result
|
Right
(
result
,
_
)
<-
results
]
parseCollectingErrors
::
TokenParser
a
->
[
Located
Token
]
->
Either
ParseError
(
a
,
[
ParseError
])
parseCollectingErrors
::
TokenParser
a
->
[
Located
Token
]
->
Either
ParseError
(
a
,
[
ParseError
])
parseCollectingErrors
parser
=
runParser
parser'
[]
""
where
parseCollectingErrors
parser
tokens
=
runParser
parser'
[]
""
tokens
where
parser'
=
do
parser'
=
do
-- Work around Parsec bug: Text.Parsec.Print.token is supposed to produce a parser that
-- sets the position by using the provided function to extract it from each token. However,
-- it doesn't bother to call this function for the *first* token, only subsequent tokens.
-- The first token is always assumed to be at 1:1. To fix this, set it manually.
case
tokens
of
Located
pos
_
:
_
->
setPosition
pos
[]
->
return
()
result
<-
parser
result
<-
parser
eof
eof
errors
<-
getState
errors
<-
getState
...
...
compiler/src/Semantics.hs
View file @
f0877237
...
@@ -30,6 +30,7 @@ import Data.Word (Word8, Word16, Word32, Word64)
...
@@ -30,6 +30,7 @@ import Data.Word (Word8, Word16, Word32, Word64)
import
Data.Char
(
chr
)
import
Data.Char
(
chr
)
import
Text.Printf
(
printf
)
import
Text.Printf
(
printf
)
import
Control.Monad
(
join
)
import
Control.Monad
(
join
)
import
Util
(
delimit
)
type
ByteString
=
[
Word8
]
type
ByteString
=
[
Word8
]
...
@@ -81,7 +82,7 @@ data BuiltinType = BuiltinVoid | BuiltinBool
...
@@ -81,7 +82,7 @@ data BuiltinType = BuiltinVoid | BuiltinBool
|
BuiltinInt8
|
BuiltinInt16
|
BuiltinInt32
|
BuiltinInt64
|
BuiltinInt8
|
BuiltinInt16
|
BuiltinInt32
|
BuiltinInt64
|
BuiltinUInt8
|
BuiltinUInt16
|
BuiltinUInt32
|
BuiltinUInt64
|
BuiltinUInt8
|
BuiltinUInt16
|
BuiltinUInt32
|
BuiltinUInt64
|
BuiltinFloat32
|
BuiltinFloat64
|
BuiltinFloat32
|
BuiltinFloat64
|
BuiltinText
|
Builtin
Bytes
|
BuiltinText
|
Builtin
Data
deriving
(
Show
,
Enum
,
Bounded
,
Eq
)
deriving
(
Show
,
Enum
,
Bounded
,
Eq
)
builtinTypes
=
[
minBound
::
BuiltinType
..
maxBound
::
BuiltinType
]
builtinTypes
=
[
minBound
::
BuiltinType
..
maxBound
::
BuiltinType
]
...
@@ -103,7 +104,10 @@ data ValueDesc = VoidDesc
...
@@ -103,7 +104,10 @@ data ValueDesc = VoidDesc
|
Float32Desc
Float
|
Float32Desc
Float
|
Float64Desc
Double
|
Float64Desc
Double
|
TextDesc
String
|
TextDesc
String
|
BytesDesc
ByteString
|
DataDesc
ByteString
|
EnumValueValueDesc
EnumValueDesc
|
StructValueDesc
[(
FieldDesc
,
ValueDesc
)]
|
ListDesc
[
ValueDesc
]
deriving
(
Show
)
deriving
(
Show
)
valueString
VoidDesc
=
error
"Can't stringify void value."
valueString
VoidDesc
=
error
"Can't stringify void value."
...
@@ -119,7 +123,11 @@ valueString (UInt64Desc i) = show i
...
@@ -119,7 +123,11 @@ valueString (UInt64Desc i) = show i
valueString
(
Float32Desc
x
)
=
show
x
valueString
(
Float32Desc
x
)
=
show
x
valueString
(
Float64Desc
x
)
=
show
x
valueString
(
Float64Desc
x
)
=
show
x
valueString
(
TextDesc
s
)
=
show
s
valueString
(
TextDesc
s
)
=
show
s
valueString
(
BytesDesc
s
)
=
show
(
map
(
chr
.
fromIntegral
)
s
)
valueString
(
DataDesc
s
)
=
show
(
map
(
chr
.
fromIntegral
)
s
)
valueString
(
EnumValueValueDesc
v
)
=
enumValueName
v
valueString
(
StructValueDesc
l
)
=
"("
++
delimit
", "
(
map
assignmentString
l
)
++
")"
where
assignmentString
(
field
,
value
)
=
fieldName
field
++
" = "
++
valueString
value
valueString
(
ListDesc
l
)
=
"["
++
delimit
", "
(
map
valueString
l
)
++
"]"
where
data
TypeDesc
=
BuiltinType
BuiltinType
data
TypeDesc
=
BuiltinType
BuiltinType
|
EnumType
EnumDesc
|
EnumType
EnumDesc
...
...
compiler/src/Token.hs
View file @
f0877237
...
@@ -26,11 +26,17 @@ module Token where
...
@@ -26,11 +26,17 @@ module Token where
import
Text.Parsec.Pos
(
SourcePos
,
sourceLine
,
sourceColumn
)
import
Text.Parsec.Pos
(
SourcePos
,
sourceLine
,
sourceColumn
)
import
Text.Printf
(
printf
)
import
Text.Printf
(
printf
)
data
Located
t
=
Located
{
locatedPos
::
SourcePos
,
locatedValue
::
t
}
deriving
(
Eq
)
data
Located
t
=
Located
{
locatedPos
::
SourcePos
,
locatedValue
::
t
}
instance
Show
t
=>
Show
(
Located
t
)
where
instance
Show
t
=>
Show
(
Located
t
)
where
show
(
Located
pos
x
)
=
printf
"%d:%d:%s"
(
sourceLine
pos
)
(
sourceColumn
pos
)
(
show
x
)
show
(
Located
pos
x
)
=
printf
"%d:%d:%s"
(
sourceLine
pos
)
(
sourceColumn
pos
)
(
show
x
)
instance
Eq
a
=>
Eq
(
Located
a
)
where
Located
_
a
==
Located
_
b
=
a
==
b
instance
Ord
a
=>
Ord
(
Located
a
)
where
compare
(
Located
_
a
)
(
Located
_
b
)
=
compare
a
b
data
Token
=
Identifier
String
data
Token
=
Identifier
String
|
ParenthesizedList
[[
Located
Token
]]
|
ParenthesizedList
[[
Located
Token
]]
|
BracketedList
[[
Located
Token
]]
|
BracketedList
[[
Located
Token
]]
...
@@ -41,6 +47,7 @@ data Token = Identifier String
...
@@ -41,6 +47,7 @@ data Token = Identifier String
|
Colon
|
Colon
|
Period
|
Period
|
EqualsSign
|
EqualsSign
|
MinusSign
|
ImportKeyword
|
ImportKeyword
|
UsingKeyword
|
UsingKeyword
|
ConstKeyword
|
ConstKeyword
...
...
compiler/src/Util.hs
0 → 100644
View file @
f0877237
-- Copyright (c) 2013, Kenton Varda <temporal@gmail.com>
-- All rights reserved.
--
-- Redistribution and use in source and binary forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- 1. Redistributions of source code must retain the above copyright notice, this
-- list of conditions and the following disclaimer.
-- 2. 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.
--
-- 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.
module
Util
where
delimit
delimiter
list
=
concat
$
loop
list
where
loop
(
""
:
t
)
=
loop
t
loop
(
a
:
""
:
t
)
=
loop
(
a
:
t
)
loop
(
a
:
b
:
t
)
=
a
:
delimiter
:
loop
(
b
:
t
)
loop
a
=
a
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment