Page Menu
Home
Xreate
Search
Configure Global Search
Log In
Docs
Questions
Repository
Issues
Patches
Internal API
Files
F2731444
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sat, Mar 14, 4:51 AM
Size
171 KB
Mime Type
text/x-diff
Expires
Mon, Mar 16, 4:51 AM (1 d, 14 h)
Engine
blob
Format
Raw Data
Handle
244046
Attached To
rXR Xreate
View Options
diff --git a/.gitignore b/.gitignore
index ab4de4e..5bbeeb6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,59 +1,66 @@
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Compiled Dynamic libraries
*.so
*.so.*
*.dylib
*.dll
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
*.class
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
# Qt-es
/.qmake.cache
/.qmake.stash
*.pro.user
*.pro.user.*
*.moc
moc_*.cpp
qrc_*.cpp
ui_*.h
Makefile*
*-build-*
# QtCreator
*.autosave
coco/*.old
coco/*~
+*~
+cpp/build-debug/*
cpp/xreate-debug/*
cpp/xreate-release/*
+cpp/.idea
+cpp/CMakeLists.txt.user*
hs/*
+project/*
+nb*.xml
+target/*
diff --git a/books/dependency-solver/potassco/clingo4.pdf b/books/dependency-solver/potassco/clingo4.pdf
new file mode 100644
index 0000000..df5c820
Binary files /dev/null and b/books/dependency-solver/potassco/clingo4.pdf differ
diff --git a/books/dependency-solver/guide.pdf b/books/dependency-solver/potassco/guide.pdf
similarity index 100%
rename from books/dependency-solver/guide.pdf
rename to books/dependency-solver/potassco/guide.pdf
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/abstract.tex b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/abstract.tex
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/abstract.tex
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/abstract.tex
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/background.tex b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/background.tex
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/background.tex
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/background.tex
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/comments.sty b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/comments.sty
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/comments.sty
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/comments.sty
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/errors.tex b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/errors.tex
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/errors.tex
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/errors.tex
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples.tex b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples.tex
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples.tex
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples.tex
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/aggr.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/aggr.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/aggr.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/aggr.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/arithc.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/arithc.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/arithc.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/arithc.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/arithf.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/arithf.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/arithf.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/arithf.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/assign.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/assign.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/assign.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/assign.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/bird.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/bird.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/bird.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/bird.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/blocks.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/blocks.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/blocks.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/blocks.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/color.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/color.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/color.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/color.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/cond.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/cond.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/cond.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/cond.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/costs.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/costs.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/costs.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/costs.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/enc_toh.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/enc_toh.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/enc_toh.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/enc_toh.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/flycn.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/flycn.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/flycn.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/flycn.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/graph.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/graph.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/graph.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/graph.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/ham.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/ham.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/ham.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/ham.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/inc.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/inc.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/inc.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/inc.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/inst_toh.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/inst_toh.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/inst_toh.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/inst_toh.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/int.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/int.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/int.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/int.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/luaf.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/luaf.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/luaf.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/luaf.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/luav.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/luav.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/luav.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/luav.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/meta.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/meta.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/meta.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/meta.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/min.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/min.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/min.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/min.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/opt.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/opt.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/opt.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/opt.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/pool.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/pool.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/pool.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/pool.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/sep.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/sep.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/sep.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/sep.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/sql.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/sql.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/sql.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/sql.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/symbc.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/symbc.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/symbc.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/symbc.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/twocond.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/twocond.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/twocond.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/twocond.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/unify.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/unify.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/unify.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/unify.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/world0.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/world0.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/world0.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/world0.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/world1.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/world1.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/world1.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/world1.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/world2.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/world2.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/world2.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/world2.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/world3.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/world3.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/world3.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/world3.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/examples/world4.lp b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/world4.lp
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/examples/world4.lp
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/examples/world4.lp
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/figures/color.tex b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/figures/color.tex
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/figures/color.tex
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/figures/color.tex
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/figures/costs.tex b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/figures/costs.tex
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/figures/costs.tex
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/figures/costs.tex
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/figures/graph.tex b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/figures/graph.tex
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/figures/graph.tex
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/figures/graph.tex
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/figures/hanoi.tex b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/figures/hanoi.tex
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/figures/hanoi.tex
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/figures/hanoi.tex
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/figures/tsp.tex b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/figures/tsp.tex
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/figures/tsp.tex
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/figures/tsp.tex
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/future.tex b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/future.tex
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/future.tex
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/future.tex
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/guide.bib b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/guide.bib
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/guide.bib
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/guide.bib
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/guide.ind b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/guide.ind
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/guide.ind
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/guide.ind
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/guide.rao b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/guide.rao
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/guide.rao
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/guide.rao
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/guide.tex b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/guide.tex
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/guide.tex
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/guide.tex
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/introduction.log b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/introduction.log
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/introduction.log
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/introduction.log
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/introduction.tex b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/introduction.tex
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/introduction.tex
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/introduction.tex
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/language.tex b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/language.tex
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/language.tex
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/language.tex
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/lparse.tex b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/lparse.tex
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/lparse.tex
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/lparse.tex
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/macro.tex b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/macro.tex
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/macro.tex
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/macro.tex
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/options.tex b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/options.tex
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/options.tex
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/options.tex
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/quickstart.tex b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/quickstart.tex
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/quickstart.tex
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/quickstart.tex
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source/rail.sty b/books/dependency-solver/potassco/potassco_guide-2010-10-04-source/rail.sty
similarity index 100%
rename from books/dependency-solver/potassco_guide-2010-10-04-source/rail.sty
rename to books/dependency-solver/potassco/potassco_guide-2010-10-04-source/rail.sty
diff --git a/books/dependency-solver/potassco_guide-2010-10-04-source.tar.gz b/books/dependency-solver/potassco_guide-2010-10-04-source.tar.gz
deleted file mode 100644
index 55653e4..0000000
Binary files a/books/dependency-solver/potassco_guide-2010-10-04-source.tar.gz and /dev/null differ
diff --git a/coco/Parser.cpp b/coco/Parser.cpp
index b41dbee..fe5a29f 100644
--- a/coco/Parser.cpp
+++ b/coco/Parser.cpp
@@ -1,496 +1,664 @@
/*----------------------------------------------------------------------
Compiler Generator Coco/R,
Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz
extended by M. Loeberbauer & A. Woess, Univ. of Linz
ported to C++ by Csaba Balazs, University of Szeged
with improvements by Pat Terry, Rhodes University
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
As an exception, it is allowed to write an extension of Coco/R that is
used as a plugin in non-free software.
If not otherwise stated, any source code generated by Coco/R (other than
Coco/R itself) does not fall under the GNU General Public License.
-----------------------------------------------------------------------*/
#include <wchar.h>
#include "Parser.h"
#include "Scanner.h"
void Parser::SynErr(int n) {
if (errDist >= minErrDist) errors->SynErr(la->line, la->col, n);
errDist = 0;
}
void Parser::SemErr(const wchar_t* msg) {
if (errDist >= minErrDist) errors->Error(t->line, t->col, msg);
errDist = 0;
}
void Parser::Get() {
for (;;) {
t = la;
la = scanner->Scan();
if (la->kind <= maxT) { ++errDist; break; }
if (dummyToken != t) {
dummyToken->kind = t->kind;
dummyToken->pos = t->pos;
dummyToken->col = t->col;
dummyToken->line = t->line;
dummyToken->next = NULL;
coco_string_delete(dummyToken->val);
dummyToken->val = coco_string_create(t->val);
t = dummyToken;
}
la = t;
}
}
void Parser::Expect(int n) {
if (la->kind==n) Get(); else { SynErr(n); }
}
void Parser::ExpectWeak(int n, int follow) {
if (la->kind == n) Get();
else {
SynErr(n);
while (!StartOf(follow)) Get();
}
}
bool Parser::WeakSeparator(int n, int syFol, int repFol) {
if (la->kind == n) {Get(); return true;}
else if (StartOf(repFol)) {return false;}
else {
SynErr(n);
while (!(StartOf(syFol) || StartOf(repFol) || StartOf(0))) {
Get();
}
return StartOf(syFol);
}
}
void Parser::Xreate() {
- while (la->kind == 1) {
- FDecl();
+ while (la->kind == _ident || la->kind == 24 /* "rule" */) {
+ if (la->kind == _ident) {
+ FDecl();
+ } else {
+ RuleDecl();
+ }
}
}
void Parser::FDecl() {
std::wstring fname; Expression fbody; std::wstring varname; TypeAnnotation typIn; TypeAnnotation typOut;
Ident(fname);
- Expect(4);
- Expect(5);
- Expect(6);
+ Expect(6 /* "=" */);
+ Expect(7 /* "function" */);
+ Expect(8 /* ":" */);
Function f = Function(fname);
if (StartOf(1)) {
Type(typOut);
f.setReturnType(typOut);
- } else if (la->kind == 7) {
+ } else if (la->kind == _lparen) {
Get();
Ident(varname);
- Expect(6);
+ Expect(8 /* ":" */);
Type(typIn);
f.addArg(varname, typIn);
- while (la->kind == 8) {
+ while (la->kind == 9 /* "," */) {
Get();
Ident(varname);
- Expect(6);
+ Expect(8 /* ":" */);
Type(typIn);
f.addArg(varname, typIn);
}
- Expect(9);
- } else SynErr(28);
- Expect(10);
- while (la->kind == 1) {
+ Expect(_rparen);
+ Expect(10 /* "->" */);
+ Type(typOut);
+ f.setReturnType(typOut);
+ while (la->kind == 9 /* "," */) {
+ Get();
+ FnTag(f);
+ }
+ } else SynErr(35);
+ Expect(11 /* "{" */);
+ while (la->kind == _ident) {
VDecl(f);
- Expect(11);
+ Expect(12 /* ";" */);
}
Expr(fbody);
- Expect(12);
- f.setBody(fbody);
+ Expect(12 /* ";" */);
+ Expect(13 /* "}" */);
+ f.setBody(fbody); root.add(f);
+}
+
+void Parser::RuleDecl() {
+ Expect(24 /* "rule" */);
+ Expect(8 /* ":" */);
+ RuleArguments args; RuleGuards guards; RuleBody body; DomainAnnotation typ;
+ Expect(_lparen);
+ Ident(arg);
+ Expect(8 /* ":" */);
+ Domain(typ);
+ args.add(arg, typ);
+ while (la->kind == 9 /* "," */) {
+ Get();
+ Ident(arg);
+ Expect(8 /* ":" */);
+ Domain(typ);
+ args.add(arg, typ);
+ }
+ Expect(_rparen);
+ if (la->kind == 25 /* "case" */) {
+ Get();
+ RGuard(guards);
+ while (la->kind == 9 /* "," */) {
+ Get();
+ RGuard(guards);
+ }
+ }
+
+ Expect(11 /* "{" */);
+ RBody(args, guards);
+ Expect(13 /* "}" */);
}
void Parser::Ident(std::wstring& name) {
- Expect(1);
+ Expect(_ident);
name = t->val;
}
void Parser::Type(TypeAnnotation& typ) {
TypeAnnotation typ2; TypeAtom typ3;
- if (la->kind == 18) {
+ if (la->kind == 19 /* "[" */) {
Get();
Type(typ2);
- Expect(19);
+ Expect(20 /* "]" */);
typ = TypeAnnotation(TypeOperator::LIST, typ2);
} else if (StartOf(2)) {
TypeTerm(typ3);
typ = TypeAnnotation(typ3);
- } else SynErr(29);
+ } else SynErr(36);
+}
+
+void Parser::FnTag(Function& f) {
+ std::wstring tag; TagModifier mod = TagModifier::NONE;
+ Ident(tag);
+ if (la->kind == 21 /* "-" */) {
+ Get();
+ TagMod(mod);
+ }
+ f.addTag(tag, mod);
}
void Parser::VDecl(Function& f) {
std::wstring vname; Expression e; TypeAnnotation typ;
Ident(vname);
- Expect(4);
- if (la->kind == 1 || la->kind == 2 || la->kind == 20) {
+ Expect(6 /* "=" */);
+ if (StartOf(3)) {
Expr(e);
- Expect(6);
+ Expect(8 /* ":" */);
Type(typ);
f.addDeclaration(vname, typ, e);
- } else if (la->kind == 18) {
+ } else if (la->kind == 19 /* "[" */) {
ListLiteral(e);
- Expect(6);
+ Expect(8 /* ":" */);
Type(typ);
f.addListDeclaration(vname, typ, e);
- } else SynErr(30);
- Expect(11);
+ } else SynErr(37);
}
void Parser::Expr(Expression& e) {
Operator op; Expression e2;
SimExpr(e);
- if (la->kind == 24 || la->kind == 25 || la->kind == 26) {
+ if (la->kind == 6 /* "=" */ || la->kind == 29 /* ">" */ || la->kind == 33 /* "<" */) {
RelOp(op);
SimExpr(e2);
- Expression e (op, e);
- e.addArg(e2);
-
+ e = Expression(op, e); e.addArg(e2);
}
}
void Parser::TypeTerm(TypeAtom& typ) {
- if (la->kind == 13) {
+ if (la->kind == 14 /* "string" */) {
Get();
- } else if (la->kind == 14) {
+ } else if (la->kind == 15 /* "int" */) {
Get();
- } else if (la->kind == 15) {
+ } else if (la->kind == 16 /* "num" */) {
Get();
- } else if (la->kind == 16) {
+ } else if (la->kind == 17 /* "float" */) {
Get();
- } else if (la->kind == 17) {
+ } else if (la->kind == 18 /* "bool" */) {
Get();
- } else SynErr(31);
+ } else SynErr(38);
typ = Atom<Type_t>(t->val);
}
void Parser::ListLiteral(Expression& e) {
Expression e2;
- Expect(18);
- if (la->kind == 19) {
- Get();
- Expect(11);
- e = Expression(Operator::LIST, Expression());
- } else if (la->kind == 1 || la->kind == 2 || la->kind == 20) {
+ Expect(19 /* "[" */);
+ e = Expression(Operator::LIST, Expression());
+ if (StartOf(3)) {
Expr(e2);
- e = Expression(Operator::LIST, e2);
- while (la->kind == 8) {
+ e.addArg(e2);
+ while (la->kind == 9 /* "," */) {
Get();
Expr(e2);
e.addArg(e2);
}
- Expect(19);
- Expect(11);
- } else SynErr(32);
+ }
+ Expect(20 /* "]" */);
+}
+
+void Parser::TagMod(TagModifier& mod) {
+ if (la->kind == 22 /* "assert" */) {
+ Get();
+ mod = TagModifier::ASSERT;
+ } else if (la->kind == 23 /* "require" */) {
+ Get();
+ mod = TagModifier::REQUIRE;
+ } else SynErr(39);
+}
+
+void Parser::Domain(DomainAnnotation& dom) {
+ if (la->kind == 7 /* "function" */) {
+ Get();
+ dom = DomainAnnotation::FUNCTION;
+ } else if (la->kind == 26 /* "variable" */) {
+ Get();
+ dom = DomainAnnotation::VARIABLE;
+ } else SynErr(40);
+}
+
+void Parser::RGuard(RuleGuards& guards) {
+ MetaExpression e;
+ MetaExpr(e);
+ guards.add(e);
+}
+
+void Parser::RBody(RuleBody& body) {
+ MetaExpr e;
+ Expect(27 /* "warning" */);
+ MetaExpr(e);
+ if (la->kind == 28 /* "message" */) {
+ Get();
+ Expect(_string);
+ }
+}
+
+void Parser::MetaExpr(MetaExpression& e) {
+ MetaExpr2(e);
+ if (la->kind == 21 /* "-" */) {
+ MetaOp(op);
+ MetaExpr2(e2);
+ MetaParameters params;
+ params.add(e);
+ params.add(e2);
+ e = MetaExpression(op, params);
+ }
+}
+
+void Parser::MetaExpr2(MetaExpression& e) {
+ std::wstring i1, i2, infix; MetaParameters params;
+ if (checkParametersList()) {
+ Ident(i1);
+ Expect(_lparen);
+ if (la->kind == _ident || la->kind == _lparen) {
+ MetaParams(params);
+ }
+ Expect(_rparen);
+ e = MetaExpression(Operator::CALL, i1, params);
+ } else if (checkInfix()) {
+ Ident(i1);
+ Ident(infix);
+ Ident(i2);
+ params.add(Expression(Atom<Identifier_t>(i1->val)));
+ params.add(Expression(Atom<Identifier_t>(i2->val)));
+ e = MetaExpression(Operator::CALL, Atom<Identifier_t>(infix->val), params);
+ } else if (la->kind == _ident) {
+ Ident(i1);
+ e = MetaExpression(Atom<Identifier_t>(i1->val));
+ } else if (la->kind == _lparen) {
+ Get();
+ MetaExpr(e);
+ Expect(_rparen);
+ } else SynErr(41);
+}
+
+void Parser::MetaOp(Operator& op) {
+ Expect(21 /* "-" */);
+ Expect(29 /* ">" */);
+ op = OPERATOR::IMPL;
+}
+
+void Parser::MetaParams(MetaParameters& params) {
+ MetaExpr e;
+ MetaExpr(e);
+ params.add(e);
+ while (la->kind == 9 /* "," */) {
+ Get();
+ MetaExpr(e);
+ params.add(e)
+ }
}
void Parser::SimExpr(Expression& e) {
Operator op; Expression e2;
Term(e);
- while (la->kind == 20 || la->kind == 21) {
+ while (la->kind == 21 /* "-" */ || la->kind == 30 /* "+" */) {
AddOp(op);
Term(e2);
- e = Expression(op, e);
- e.addArg(e2);
-
+ e = Expression(op, e); e.addArg(e2);
}
}
void Parser::RelOp(Operator& op) {
op = Operator::EQU;
- if (la->kind == 24) {
+ if (la->kind == 6 /* "=" */) {
Get();
- } else if (la->kind == 25) {
+ Expect(6 /* "=" */);
+ } else if (la->kind == 33 /* "<" */) {
Get();
op = Operator::LSS;
- } else if (la->kind == 26) {
+ } else if (la->kind == 29 /* ">" */) {
Get();
op = Operator::GTR;
- } else SynErr(33);
+ } else SynErr(42);
}
void Parser::Term(Expression& e) {
Operator op; Expression e2;
Factor(e);
- while (la->kind == 22 || la->kind == 23) {
+ while (la->kind == 31 /* "*" */ || la->kind == 32 /* "/" */) {
MulOp(op);
Factor(e2);
- e = Expression(op, e);
- e.addArg(e2);
-
+ e = Expression(op, e); e.addArg(e2);
}
}
void Parser::AddOp(Operator& op) {
op = Operator::ADD;
- if (la->kind == 21) {
+ if (la->kind == 30 /* "+" */) {
Get();
- } else if (la->kind == 20) {
+ } else if (la->kind == 21 /* "-" */) {
Get();
op = Operator::SUB;
- } else SynErr(34);
+ } else SynErr(43);
}
void Parser::Factor(Expression& e) {
- std::wstring name;
- if (la->kind == 1) {
+ std::wstring name;
+ if (checkParametersList()) {
+ Ident(name);
+ e = Expression(Operator::CALL, Atom<Identifier_t>(name));
+ Expect(_lparen);
+ if (StartOf(3)) {
+ CalleeParams(e);
+ }
+ Expect(_rparen);
+ } else if (la->kind == _ident) {
Ident(name);
e = Expression(Atom<Identifier_t>(name));
- } else if (la->kind == 2) {
+ } else if (la->kind == _number) {
Get();
e = Expression(Atom<Number_t>(t->val));
- } else if (la->kind == 20) {
+ } else if (la->kind == 21 /* "-" */) {
Get();
Factor(e);
e = Expression(Operator::NEG, e);
- } else SynErr(35);
+ } else if (la->kind == _lparen) {
+ Get();
+ Expr(e);
+ Expect(_rparen);
+ } else SynErr(44);
}
void Parser::MulOp(Operator& op) {
op = Operator::MUL;
- if (la->kind == 22) {
+ if (la->kind == 31 /* "*" */) {
Get();
- } else if (la->kind == 23) {
+ } else if (la->kind == 32 /* "/" */) {
Get();
op = Operator::DIV;
- } else SynErr(36);
+ } else SynErr(45);
+}
+
+void Parser::CalleeParams(Expression& e) {
+ Expression e2;
+ Expr(e2);
+ e.addArg(e2);
+ while (la->kind == 9 /* "," */) {
+ Get();
+ Expr(e2);
+ e.addArg(e2);
+ }
}
// If the user declared a method Init and a mehtod Destroy they should
// be called in the contructur and the destructor respctively.
//
// The following templates are used to recognize if the user declared
// the methods Init and Destroy.
template<typename T>
struct ParserInitExistsRecognizer {
template<typename U, void (U::*)() = &U::Init>
struct ExistsIfInitIsDefinedMarker{};
struct InitIsMissingType {
char dummy1;
};
struct InitExistsType {
char dummy1; char dummy2;
};
// exists always
template<typename U>
static InitIsMissingType is_here(...);
// exist only if ExistsIfInitIsDefinedMarker is defined
template<typename U>
static InitExistsType is_here(ExistsIfInitIsDefinedMarker<U>*);
enum { InitExists = (sizeof(is_here<T>(NULL)) == sizeof(InitExistsType)) };
};
template<typename T>
struct ParserDestroyExistsRecognizer {
template<typename U, void (U::*)() = &U::Destroy>
struct ExistsIfDestroyIsDefinedMarker{};
struct DestroyIsMissingType {
char dummy1;
};
struct DestroyExistsType {
char dummy1; char dummy2;
};
// exists always
template<typename U>
static DestroyIsMissingType is_here(...);
// exist only if ExistsIfDestroyIsDefinedMarker is defined
template<typename U>
static DestroyExistsType is_here(ExistsIfDestroyIsDefinedMarker<U>*);
enum { DestroyExists = (sizeof(is_here<T>(NULL)) == sizeof(DestroyExistsType)) };
};
// The folloing templates are used to call the Init and Destroy methods if they exist.
// Generic case of the ParserInitCaller, gets used if the Init method is missing
template<typename T, bool = ParserInitExistsRecognizer<T>::InitExists>
struct ParserInitCaller {
static void CallInit(T *t) {
// nothing to do
}
};
// True case of the ParserInitCaller, gets used if the Init method exists
template<typename T>
struct ParserInitCaller<T, true> {
static void CallInit(T *t) {
t->Init();
}
};
// Generic case of the ParserDestroyCaller, gets used if the Destroy method is missing
template<typename T, bool = ParserDestroyExistsRecognizer<T>::DestroyExists>
struct ParserDestroyCaller {
static void CallDestroy(T *t) {
// nothing to do
}
};
// True case of the ParserDestroyCaller, gets used if the Destroy method exists
template<typename T>
struct ParserDestroyCaller<T, true> {
static void CallDestroy(T *t) {
t->Destroy();
}
};
void Parser::Parse() {
t = NULL;
la = dummyToken = new Token();
la->val = coco_string_create(L"Dummy Token");
Get();
Xreate();
Expect(0);
}
Parser::Parser(Scanner *scanner) {
- maxT = 27;
+ maxT = 34;
ParserInitCaller<Parser>::CallInit(this);
dummyToken = NULL;
t = la = NULL;
minErrDist = 2;
errDist = minErrDist;
this->scanner = scanner;
errors = new Errors();
}
bool Parser::StartOf(int s) {
const bool T = true;
const bool x = false;
- static bool set[3][29] = {
- {T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x},
- {x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,T, T,T,T,x, x,x,x,x, x,x,x,x, x},
- {x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,T, T,T,x,x, x,x,x,x, x,x,x,x, x}
+ static bool set[4][36] = {
+ {T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
+ {x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,T, T,T,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
+ {x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,T, T,T,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
+ {x,T,T,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x}
};
return set[s][la->kind];
}
Parser::~Parser() {
ParserDestroyCaller<Parser>::CallDestroy(this);
delete errors;
delete dummyToken;
}
Errors::Errors() {
count = 0;
}
void Errors::SynErr(int line, int col, int n) {
wchar_t* s;
switch (n) {
case 0: s = coco_string_create(L"EOF expected"); break;
case 1: s = coco_string_create(L"ident expected"); break;
case 2: s = coco_string_create(L"number expected"); break;
case 3: s = coco_string_create(L"string expected"); break;
- case 4: s = coco_string_create(L"\"=\" expected"); break;
- case 5: s = coco_string_create(L"\"function\" expected"); break;
- case 6: s = coco_string_create(L"\":\" expected"); break;
- case 7: s = coco_string_create(L"\"(\" expected"); break;
- case 8: s = coco_string_create(L"\",\" expected"); break;
- case 9: s = coco_string_create(L"\")\" expected"); break;
- case 10: s = coco_string_create(L"\"{\" expected"); break;
- case 11: s = coco_string_create(L"\";\" expected"); break;
- case 12: s = coco_string_create(L"\"}\" expected"); break;
- case 13: s = coco_string_create(L"\"string\" expected"); break;
- case 14: s = coco_string_create(L"\"int\" expected"); break;
- case 15: s = coco_string_create(L"\"num\" expected"); break;
- case 16: s = coco_string_create(L"\"float\" expected"); break;
- case 17: s = coco_string_create(L"\"bool\" expected"); break;
- case 18: s = coco_string_create(L"\"[\" expected"); break;
- case 19: s = coco_string_create(L"\"]\" expected"); break;
- case 20: s = coco_string_create(L"\"-\" expected"); break;
- case 21: s = coco_string_create(L"\"+\" expected"); break;
- case 22: s = coco_string_create(L"\"*\" expected"); break;
- case 23: s = coco_string_create(L"\"/\" expected"); break;
- case 24: s = coco_string_create(L"\"==\" expected"); break;
- case 25: s = coco_string_create(L"\"<\" expected"); break;
- case 26: s = coco_string_create(L"\">\" expected"); break;
- case 27: s = coco_string_create(L"??? expected"); break;
- case 28: s = coco_string_create(L"invalid FDecl"); break;
- case 29: s = coco_string_create(L"invalid Type"); break;
- case 30: s = coco_string_create(L"invalid VDecl"); break;
- case 31: s = coco_string_create(L"invalid TypeTerm"); break;
- case 32: s = coco_string_create(L"invalid ListLiteral"); break;
- case 33: s = coco_string_create(L"invalid RelOp"); break;
- case 34: s = coco_string_create(L"invalid AddOp"); break;
- case 35: s = coco_string_create(L"invalid Factor"); break;
- case 36: s = coco_string_create(L"invalid MulOp"); break;
+ case 4: s = coco_string_create(L"lparen expected"); break;
+ case 5: s = coco_string_create(L"rparen expected"); break;
+ case 6: s = coco_string_create(L"\"=\" expected"); break;
+ case 7: s = coco_string_create(L"\"function\" expected"); break;
+ case 8: s = coco_string_create(L"\":\" expected"); break;
+ case 9: s = coco_string_create(L"\",\" expected"); break;
+ case 10: s = coco_string_create(L"\"->\" expected"); break;
+ case 11: s = coco_string_create(L"\"{\" expected"); break;
+ case 12: s = coco_string_create(L"\";\" expected"); break;
+ case 13: s = coco_string_create(L"\"}\" expected"); break;
+ case 14: s = coco_string_create(L"\"string\" expected"); break;
+ case 15: s = coco_string_create(L"\"int\" expected"); break;
+ case 16: s = coco_string_create(L"\"num\" expected"); break;
+ case 17: s = coco_string_create(L"\"float\" expected"); break;
+ case 18: s = coco_string_create(L"\"bool\" expected"); break;
+ case 19: s = coco_string_create(L"\"[\" expected"); break;
+ case 20: s = coco_string_create(L"\"]\" expected"); break;
+ case 21: s = coco_string_create(L"\"-\" expected"); break;
+ case 22: s = coco_string_create(L"\"assert\" expected"); break;
+ case 23: s = coco_string_create(L"\"require\" expected"); break;
+ case 24: s = coco_string_create(L"\"rule\" expected"); break;
+ case 25: s = coco_string_create(L"\"case\" expected"); break;
+ case 26: s = coco_string_create(L"\"variable\" expected"); break;
+ case 27: s = coco_string_create(L"\"warning\" expected"); break;
+ case 28: s = coco_string_create(L"\"message\" expected"); break;
+ case 29: s = coco_string_create(L"\">\" expected"); break;
+ case 30: s = coco_string_create(L"\"+\" expected"); break;
+ case 31: s = coco_string_create(L"\"*\" expected"); break;
+ case 32: s = coco_string_create(L"\"/\" expected"); break;
+ case 33: s = coco_string_create(L"\"<\" expected"); break;
+ case 34: s = coco_string_create(L"??? expected"); break;
+ case 35: s = coco_string_create(L"invalid FDecl"); break;
+ case 36: s = coco_string_create(L"invalid Type"); break;
+ case 37: s = coco_string_create(L"invalid VDecl"); break;
+ case 38: s = coco_string_create(L"invalid TypeTerm"); break;
+ case 39: s = coco_string_create(L"invalid TagMod"); break;
+ case 40: s = coco_string_create(L"invalid Domain"); break;
+ case 41: s = coco_string_create(L"invalid MetaExpr2"); break;
+ case 42: s = coco_string_create(L"invalid RelOp"); break;
+ case 43: s = coco_string_create(L"invalid AddOp"); break;
+ case 44: s = coco_string_create(L"invalid Factor"); break;
+ case 45: s = coco_string_create(L"invalid MulOp"); break;
default:
{
wchar_t format[20];
coco_swprintf(format, 20, L"error %d", n);
s = coco_string_create(format);
}
break;
}
wprintf(L"-- line %d col %d: %ls\n", line, col, s);
coco_string_delete(s);
count++;
}
void Errors::Error(int line, int col, const wchar_t *s) {
wprintf(L"-- line %d col %d: %ls\n", line, col, s);
count++;
}
void Errors::Warning(int line, int col, const wchar_t *s) {
wprintf(L"-- line %d col %d: %ls\n", line, col, s);
}
void Errors::Warning(const wchar_t *s) {
wprintf(L"%ls\n", s);
}
void Errors::Exception(const wchar_t* s) {
wprintf(L"%ls", s);
exit(1);
}
diff --git a/coco/Parser.h b/coco/Parser.h
index b0cb7da..8501f6d 100644
--- a/coco/Parser.h
+++ b/coco/Parser.h
@@ -1,112 +1,141 @@
/*----------------------------------------------------------------------
Compiler Generator Coco/R,
Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz
extended by M. Loeberbauer & A. Woess, Univ. of Linz
ported to C++ by Csaba Balazs, University of Szeged
with improvements by Pat Terry, Rhodes University
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
As an exception, it is allowed to write an extension of Coco/R that is
used as a plugin in non-free software.
If not otherwise stated, any source code generated by Coco/R (other than
Coco/R itself) does not fall under the GNU General Public License.
-----------------------------------------------------------------------*/
#if !defined(COCO_PARSER_H__)
#define COCO_PARSER_H__
#include "ast.h"
#include <string>
#include "Scanner.h"
class Errors {
public:
int count; // number of errors detected
Errors();
void SynErr(int line, int col, int n);
void Error(int line, int col, const wchar_t *s);
void Warning(int line, int col, const wchar_t *s);
void Warning(const wchar_t *s);
void Exception(const wchar_t *s);
}; // Errors
class Parser {
private:
enum {
_EOF=0,
_ident=1,
_number=2,
- _string=3
+ _string=3,
+ _lparen=4,
+ _rparen=5
};
int maxT;
Token *dummyToken;
int errDist;
int minErrDist;
void SynErr(int n);
void Get();
void Expect(int n);
bool StartOf(int s);
void ExpectWeak(int n, int follow);
bool WeakSeparator(int n, int syFol, int repFol);
public:
Scanner *scanner;
Errors *errors;
Token *t; // last recognized token
Token *la; // lookahead token
AST root; // current program unit (procedure or main program)
+bool checkParametersList()
+{
+ scanner.ResetPeek();
+ Token x = scanner->Peek();
+ return la->kind == _ident && x->kind == _lparen;
+}
+
+bool checkInfix()
+{
+ scanner.ResetPeek();
+ Token x = scanner->Peek();
+ return la->kind == _ident && x->kind == _ident;
+}
+
+bool check
+
Parser(Scanner *scanner);
~Parser();
void SemErr(const wchar_t* msg);
void Xreate();
void FDecl();
+ void RuleDecl();
void Ident(std::wstring& name);
void Type(TypeAnnotation& typ);
+ void FnTag(Function& f);
void VDecl(Function& f);
void Expr(Expression& e);
void TypeTerm(TypeAtom& typ);
void ListLiteral(Expression& e);
+ void TagMod(TagModifier& mod);
+ void Domain(DomainAnnotation& dom);
+ void RGuard(RuleGuards& guards);
+ void RBody(RuleBody& body);
+ void MetaExpr(MetaExpression& e);
+ void MetaExpr2(MetaExpression& e);
+ void MetaOp(Operator& op);
+ void MetaParams(MetaParameters& params);
void SimExpr(Expression& e);
void RelOp(Operator& op);
void Term(Expression& e);
void AddOp(Operator& op);
void Factor(Expression& e);
void MulOp(Operator& op);
+ void CalleeParams(Expression& e);
void Parse();
}; // end Parser
#endif
diff --git a/coco/Scanner.cpp b/coco/Scanner.cpp
index c16b3f3..f19591f 100644
--- a/coco/Scanner.cpp
+++ b/coco/Scanner.cpp
@@ -1,756 +1,764 @@
/*----------------------------------------------------------------------
Compiler Generator Coco/R,
Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz
extended by M. Loeberbauer & A. Woess, Univ. of Linz
ported to C++ by Csaba Balazs, University of Szeged
with improvements by Pat Terry, Rhodes University
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
As an exception, it is allowed to write an extension of Coco/R that is
used as a plugin in non-free software.
If not otherwise stated, any source code generated by Coco/R (other than
Coco/R itself) does not fall under the GNU General Public License.
-----------------------------------------------------------------------*/
#include <memory.h>
#include <string.h>
#include "Scanner.h"
+
+
+
// string handling, wide character
wchar_t* coco_string_create(const wchar_t* value) {
return coco_string_create(value, 0);
}
wchar_t* coco_string_create(const wchar_t *value, int startIndex) {
int valueLen = 0;
int len = 0;
if (value) {
valueLen = wcslen(value);
len = valueLen - startIndex;
}
return coco_string_create(value, startIndex, len);
}
wchar_t* coco_string_create(const wchar_t *value, int startIndex, int length) {
int len = 0;
wchar_t* data;
if (value) { len = length; }
data = new wchar_t[len + 1];
wcsncpy(data, &(value[startIndex]), len);
data[len] = 0;
return data;
}
wchar_t* coco_string_create_upper(const wchar_t* data) {
if (!data) { return NULL; }
int dataLen = 0;
if (data) { dataLen = wcslen(data); }
wchar_t *newData = new wchar_t[dataLen + 1];
for (int i = 0; i <= dataLen; i++) {
if ((L'a' <= data[i]) && (data[i] <= L'z')) {
newData[i] = data[i] + (L'A' - L'a');
}
else { newData[i] = data[i]; }
}
newData[dataLen] = L'\0';
return newData;
}
wchar_t* coco_string_create_lower(const wchar_t* data) {
if (!data) { return NULL; }
int dataLen = wcslen(data);
return coco_string_create_lower(data, 0, dataLen);
}
wchar_t* coco_string_create_lower(const wchar_t* data, int startIndex, int dataLen) {
if (!data) { return NULL; }
wchar_t* newData = new wchar_t[dataLen + 1];
for (int i = 0; i <= dataLen; i++) {
wchar_t ch = data[startIndex + i];
if ((L'A' <= ch) && (ch <= L'Z')) {
newData[i] = ch - (L'A' - L'a');
}
else { newData[i] = ch; }
}
newData[dataLen] = L'\0';
return newData;
}
wchar_t* coco_string_create_append(const wchar_t* data1, const wchar_t* data2) {
wchar_t* data;
int data1Len = 0;
int data2Len = 0;
if (data1) { data1Len = wcslen(data1); }
if (data2) {data2Len = wcslen(data2); }
data = new wchar_t[data1Len + data2Len + 1];
if (data1) { wcscpy(data, data1); }
if (data2) { wcscpy(data + data1Len, data2); }
data[data1Len + data2Len] = 0;
return data;
}
wchar_t* coco_string_create_append(const wchar_t *target, const wchar_t appendix) {
int targetLen = coco_string_length(target);
wchar_t* data = new wchar_t[targetLen + 2];
wcsncpy(data, target, targetLen);
data[targetLen] = appendix;
data[targetLen + 1] = 0;
return data;
}
void coco_string_delete(wchar_t* &data) {
delete [] data;
data = NULL;
}
int coco_string_length(const wchar_t* data) {
if (data) { return wcslen(data); }
return 0;
}
bool coco_string_endswith(const wchar_t* data, const wchar_t *end) {
int dataLen = wcslen(data);
int endLen = wcslen(end);
return (endLen <= dataLen) && (wcscmp(data + dataLen - endLen, end) == 0);
}
int coco_string_indexof(const wchar_t* data, const wchar_t value) {
const wchar_t* chr = wcschr(data, value);
if (chr) { return (chr-data); }
return -1;
}
int coco_string_lastindexof(const wchar_t* data, const wchar_t value) {
const wchar_t* chr = wcsrchr(data, value);
if (chr) { return (chr-data); }
return -1;
}
void coco_string_merge(wchar_t* &target, const wchar_t* appendix) {
if (!appendix) { return; }
wchar_t* data = coco_string_create_append(target, appendix);
delete [] target;
target = data;
}
bool coco_string_equal(const wchar_t* data1, const wchar_t* data2) {
return wcscmp( data1, data2 ) == 0;
}
int coco_string_compareto(const wchar_t* data1, const wchar_t* data2) {
return wcscmp(data1, data2);
}
int coco_string_hash(const wchar_t *data) {
int h = 0;
if (!data) { return 0; }
while (*data != 0) {
h = (h * 7) ^ *data;
++data;
}
if (h < 0) { h = -h; }
return h;
}
// string handling, ascii character
wchar_t* coco_string_create(const char* value) {
int len = 0;
if (value) { len = strlen(value); }
wchar_t* data = new wchar_t[len + 1];
for (int i = 0; i < len; ++i) { data[i] = (wchar_t) value[i]; }
data[len] = 0;
return data;
}
char* coco_string_create_char(const wchar_t *value) {
int len = coco_string_length(value);
char *res = new char[len + 1];
for (int i = 0; i < len; ++i) { res[i] = (char) value[i]; }
res[len] = 0;
return res;
}
void coco_string_delete(char* &data) {
delete [] data;
data = NULL;
}
-
-
Token::Token() {
kind = 0;
pos = 0;
col = 0;
line = 0;
val = NULL;
next = NULL;
}
Token::~Token() {
coco_string_delete(val);
}
Buffer::Buffer(FILE* s, bool isUserStream) {
// ensure binary read on windows
#if _MSC_VER >= 1300
_setmode(_fileno(s), _O_BINARY);
#endif
stream = s; this->isUserStream = isUserStream;
if (CanSeek()) {
fseek(s, 0, SEEK_END);
fileLen = ftell(s);
fseek(s, 0, SEEK_SET);
- bufLen = (fileLen < MAX_BUFFER_LENGTH) ? fileLen : MAX_BUFFER_LENGTH;
+ bufLen = (fileLen < COCO_MAX_BUFFER_LENGTH) ? fileLen : COCO_MAX_BUFFER_LENGTH;
bufStart = INT_MAX; // nothing in the buffer so far
} else {
fileLen = bufLen = bufStart = 0;
}
- bufCapacity = (bufLen>0) ? bufLen : MIN_BUFFER_LENGTH;
+ bufCapacity = (bufLen>0) ? bufLen : COCO_MIN_BUFFER_LENGTH;
buf = new unsigned char[bufCapacity];
if (fileLen > 0) SetPos(0); // setup buffer to position 0 (start)
else bufPos = 0; // index 0 is already after the file, thus Pos = 0 is invalid
if (bufLen == fileLen && CanSeek()) Close();
}
Buffer::Buffer(Buffer *b) {
buf = b->buf;
bufCapacity = b->bufCapacity;
b->buf = NULL;
bufStart = b->bufStart;
bufLen = b->bufLen;
fileLen = b->fileLen;
bufPos = b->bufPos;
stream = b->stream;
b->stream = NULL;
isUserStream = b->isUserStream;
}
Buffer::Buffer(const unsigned char* buf, int len) {
this->buf = new unsigned char[len];
memcpy(this->buf, buf, len*sizeof(unsigned char));
bufStart = 0;
bufCapacity = bufLen = len;
fileLen = len;
bufPos = 0;
stream = NULL;
}
Buffer::~Buffer() {
Close();
if (buf != NULL) {
delete [] buf;
buf = NULL;
}
}
void Buffer::Close() {
if (!isUserStream && stream != NULL) {
fclose(stream);
stream = NULL;
}
}
int Buffer::Read() {
if (bufPos < bufLen) {
return buf[bufPos++];
} else if (GetPos() < fileLen) {
SetPos(GetPos()); // shift buffer start to Pos
return buf[bufPos++];
} else if ((stream != NULL) && !CanSeek() && (ReadNextStreamChunk() > 0)) {
return buf[bufPos++];
} else {
return EoF;
}
}
int Buffer::Peek() {
int curPos = GetPos();
int ch = Read();
SetPos(curPos);
return ch;
}
// beg .. begin, zero-based, inclusive, in byte
// end .. end, zero-based, exclusive, in byte
wchar_t* Buffer::GetString(int beg, int end) {
int len = 0;
wchar_t *buf = new wchar_t[end - beg];
int oldPos = GetPos();
SetPos(beg);
while (GetPos() < end) buf[len++] = (wchar_t) Read();
SetPos(oldPos);
wchar_t *res = coco_string_create(buf, 0, len);
coco_string_delete(buf);
return res;
}
int Buffer::GetPos() {
return bufPos + bufStart;
}
void Buffer::SetPos(int value) {
if ((value >= fileLen) && (stream != NULL) && !CanSeek()) {
// Wanted position is after buffer and the stream
// is not seek-able e.g. network or console,
// thus we have to read the stream manually till
// the wanted position is in sight.
while ((value >= fileLen) && (ReadNextStreamChunk() > 0));
}
if ((value < 0) || (value > fileLen)) {
wprintf(L"--- buffer out of bounds access, position: %d\n", value);
exit(1);
}
if ((value >= bufStart) && (value < (bufStart + bufLen))) { // already in buffer
bufPos = value - bufStart;
} else if (stream != NULL) { // must be swapped in
fseek(stream, value, SEEK_SET);
bufLen = fread(buf, sizeof(unsigned char), bufCapacity, stream);
bufStart = value; bufPos = 0;
} else {
bufPos = fileLen - bufStart; // make Pos return fileLen
}
}
// Read the next chunk of bytes from the stream, increases the buffer
// if needed and updates the fields fileLen and bufLen.
// Returns the number of bytes read.
int Buffer::ReadNextStreamChunk() {
int free = bufCapacity - bufLen;
if (free == 0) {
// in the case of a growing input stream
// we can neither seek in the stream, nor can we
// foresee the maximum length, thus we must adapt
// the buffer size on demand.
bufCapacity = bufLen * 2;
unsigned char *newBuf = new unsigned char[bufCapacity];
memcpy(newBuf, buf, bufLen*sizeof(unsigned char));
delete [] buf;
buf = newBuf;
free = bufLen;
}
int read = fread(buf + bufLen, sizeof(unsigned char), free, stream);
if (read > 0) {
fileLen = bufLen = (bufLen + read);
return read;
}
// end of stream reached
return 0;
}
bool Buffer::CanSeek() {
return (stream != NULL) && (ftell(stream) != -1);
}
int UTF8Buffer::Read() {
int ch;
do {
ch = Buffer::Read();
// until we find a utf8 start (0xxxxxxx or 11xxxxxx)
} while ((ch >= 128) && ((ch & 0xC0) != 0xC0) && (ch != EoF));
if (ch < 128 || ch == EoF) {
// nothing to do, first 127 chars are the same in ascii and utf8
// 0xxxxxxx or end of file character
} else if ((ch & 0xF0) == 0xF0) {
// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
int c1 = ch & 0x07; ch = Buffer::Read();
int c2 = ch & 0x3F; ch = Buffer::Read();
int c3 = ch & 0x3F; ch = Buffer::Read();
int c4 = ch & 0x3F;
ch = (((((c1 << 6) | c2) << 6) | c3) << 6) | c4;
} else if ((ch & 0xE0) == 0xE0) {
// 1110xxxx 10xxxxxx 10xxxxxx
int c1 = ch & 0x0F; ch = Buffer::Read();
int c2 = ch & 0x3F; ch = Buffer::Read();
int c3 = ch & 0x3F;
ch = (((c1 << 6) | c2) << 6) | c3;
} else if ((ch & 0xC0) == 0xC0) {
// 110xxxxx 10xxxxxx
int c1 = ch & 0x1F; ch = Buffer::Read();
int c2 = ch & 0x3F;
ch = (c1 << 6) | c2;
}
return ch;
}
Scanner::Scanner(const unsigned char* buf, int len) {
buffer = new Buffer(buf, len);
Init();
}
Scanner::Scanner(const wchar_t* fileName) {
FILE* stream;
char *chFileName = coco_string_create_char(fileName);
if ((stream = fopen(chFileName, "rb")) == NULL) {
wprintf(L"--- Cannot open file %ls\n", fileName);
exit(1);
}
coco_string_delete(chFileName);
buffer = new Buffer(stream, false);
Init();
}
Scanner::Scanner(FILE* s) {
buffer = new Buffer(s, true);
Init();
}
Scanner::~Scanner() {
char* cur = (char*) firstHeap;
while(cur != NULL) {
- cur = *(char**) (cur + HEAP_BLOCK_SIZE);
+ cur = *(char**) (cur + COCO_HEAP_BLOCK_SIZE);
free(firstHeap);
firstHeap = cur;
}
delete [] tval;
delete buffer;
}
void Scanner::Init() {
EOL = '\n';
eofSym = 0;
- maxT = 27;
- noSym = 27;
+ maxT = 34;
+ noSym = 34;
int i;
for (i = 65; i <= 90; ++i) start.set(i, 1);
for (i = 97; i <= 122; ++i) start.set(i, 1);
for (i = 48; i <= 57; ++i) start.set(i, 2);
start.set(34, 3);
- start.set(61, 21);
- start.set(58, 5);
- start.set(40, 6);
- start.set(44, 7);
- start.set(41, 8);
- start.set(123, 9);
- start.set(59, 10);
- start.set(125, 11);
- start.set(91, 12);
- start.set(93, 13);
- start.set(45, 14);
- start.set(43, 15);
- start.set(42, 16);
- start.set(47, 17);
- start.set(60, 19);
- start.set(62, 20);
+ start.set(40, 5);
+ start.set(41, 6);
+ start.set(61, 7);
+ start.set(58, 8);
+ start.set(44, 9);
+ start.set(45, 21);
+ start.set(123, 11);
+ start.set(59, 12);
+ start.set(125, 13);
+ start.set(91, 14);
+ start.set(93, 15);
+ start.set(62, 16);
+ start.set(43, 17);
+ start.set(42, 18);
+ start.set(47, 19);
+ start.set(60, 20);
start.set(Buffer::EoF, -1);
- keywords.set(L"function", 5);
- keywords.set(L"string", 13);
- keywords.set(L"int", 14);
- keywords.set(L"num", 15);
- keywords.set(L"float", 16);
- keywords.set(L"bool", 17);
+ keywords.set(L"function", 7);
+ keywords.set(L"string", 14);
+ keywords.set(L"int", 15);
+ keywords.set(L"num", 16);
+ keywords.set(L"float", 17);
+ keywords.set(L"bool", 18);
+ keywords.set(L"assert", 22);
+ keywords.set(L"require", 23);
+ keywords.set(L"rule", 24);
+ keywords.set(L"case", 25);
+ keywords.set(L"variable", 26);
+ keywords.set(L"warning", 27);
+ keywords.set(L"message", 28);
tvalLength = 128;
tval = new wchar_t[tvalLength]; // text of current token
- // HEAP_BLOCK_SIZE byte heap + pointer to next heap block
- heap = malloc(HEAP_BLOCK_SIZE + sizeof(void*));
+ // COCO_HEAP_BLOCK_SIZE byte heap + pointer to next heap block
+ heap = malloc(COCO_HEAP_BLOCK_SIZE + sizeof(void*));
firstHeap = heap;
- heapEnd = (void**) (((char*) heap) + HEAP_BLOCK_SIZE);
+ heapEnd = (void**) (((char*) heap) + COCO_HEAP_BLOCK_SIZE);
*heapEnd = 0;
heapTop = heap;
- if (sizeof(Token) > HEAP_BLOCK_SIZE) {
- wprintf(L"--- Too small HEAP_BLOCK_SIZE\n");
+ if (sizeof(Token) > COCO_HEAP_BLOCK_SIZE) {
+ wprintf(L"--- Too small COCO_HEAP_BLOCK_SIZE\n");
exit(1);
}
pos = -1; line = 1; col = 0; charPos = -1;
oldEols = 0;
NextCh();
if (ch == 0xEF) { // check optional byte order mark for UTF-8
NextCh(); int ch1 = ch;
NextCh(); int ch2 = ch;
if (ch1 != 0xBB || ch2 != 0xBF) {
wprintf(L"Illegal byte order mark at start of file");
exit(1);
}
Buffer *oldBuf = buffer;
buffer = new UTF8Buffer(buffer); col = 0; charPos = -1;
delete oldBuf; oldBuf = NULL;
NextCh();
}
pt = tokens = CreateToken(); // first token is a dummy
}
void Scanner::NextCh() {
if (oldEols > 0) { ch = EOL; oldEols--; }
else {
pos = buffer->GetPos();
// buffer reads unicode chars, if UTF8 has been detected
ch = buffer->Read(); col++; charPos++;
// replace isolated '\r' by '\n' in order to make
// eol handling uniform across Windows, Unix and Mac
if (ch == L'\r' && buffer->Peek() != L'\n') ch = EOL;
if (ch == EOL) { line++; col = 0; }
}
}
void Scanner::AddCh() {
if (tlen >= tvalLength) {
tvalLength *= 2;
wchar_t *newBuf = new wchar_t[tvalLength];
memcpy(newBuf, tval, tlen*sizeof(wchar_t));
delete [] tval;
tval = newBuf;
}
if (ch != Buffer::EoF) {
tval[tlen++] = ch;
NextCh();
}
}
bool Scanner::Comment0() {
int level = 1, pos0 = pos, line0 = line, col0 = col, charPos0 = charPos;
NextCh();
if (ch == L'/') {
NextCh();
for(;;) {
if (ch == 10) {
level--;
if (level == 0) { oldEols = line - line0; NextCh(); return true; }
NextCh();
} else if (ch == buffer->EoF) return false;
else NextCh();
}
} else {
buffer->SetPos(pos0); NextCh(); line = line0; col = col0; charPos = charPos0;
}
return false;
}
bool Scanner::Comment1() {
int level = 1, pos0 = pos, line0 = line, col0 = col, charPos0 = charPos;
NextCh();
if (ch == L'*') {
NextCh();
for(;;) {
if (ch == L'*') {
NextCh();
if (ch == L'/') {
level--;
if (level == 0) { oldEols = line - line0; NextCh(); return true; }
NextCh();
}
} else if (ch == L'/') {
NextCh();
if (ch == L'*') {
level++; NextCh();
}
} else if (ch == buffer->EoF) return false;
else NextCh();
}
} else {
buffer->SetPos(pos0); NextCh(); line = line0; col = col0; charPos = charPos0;
}
return false;
}
void Scanner::CreateHeapBlock() {
void* newHeap;
char* cur = (char*) firstHeap;
- while(((char*) tokens < cur) || ((char*) tokens > (cur + HEAP_BLOCK_SIZE))) {
- cur = *((char**) (cur + HEAP_BLOCK_SIZE));
+ while(((char*) tokens < cur) || ((char*) tokens > (cur + COCO_HEAP_BLOCK_SIZE))) {
+ cur = *((char**) (cur + COCO_HEAP_BLOCK_SIZE));
free(firstHeap);
firstHeap = cur;
}
- // HEAP_BLOCK_SIZE byte heap + pointer to next heap block
- newHeap = malloc(HEAP_BLOCK_SIZE + sizeof(void*));
+ // COCO_HEAP_BLOCK_SIZE byte heap + pointer to next heap block
+ newHeap = malloc(COCO_HEAP_BLOCK_SIZE + sizeof(void*));
*heapEnd = newHeap;
- heapEnd = (void**) (((char*) newHeap) + HEAP_BLOCK_SIZE);
+ heapEnd = (void**) (((char*) newHeap) + COCO_HEAP_BLOCK_SIZE);
*heapEnd = 0;
heap = newHeap;
heapTop = heap;
}
Token* Scanner::CreateToken() {
Token *t;
if (((char*) heapTop + (int) sizeof(Token)) >= (char*) heapEnd) {
CreateHeapBlock();
}
t = (Token*) heapTop;
heapTop = (void*) ((char*) heapTop + sizeof(Token));
t->val = NULL;
t->next = NULL;
return t;
}
void Scanner::AppendVal(Token *t) {
int reqMem = (tlen + 1) * sizeof(wchar_t);
if (((char*) heapTop + reqMem) >= (char*) heapEnd) {
- if (reqMem > HEAP_BLOCK_SIZE) {
+ if (reqMem > COCO_HEAP_BLOCK_SIZE) {
wprintf(L"--- Too long token value\n");
exit(1);
}
CreateHeapBlock();
}
t->val = (wchar_t*) heapTop;
heapTop = (void*) ((char*) heapTop + reqMem);
wcsncpy(t->val, tval, tlen);
t->val[tlen] = L'\0';
}
Token* Scanner::NextToken() {
while (ch == ' ' ||
(ch >= 9 && ch <= 10) || ch == 13
) NextCh();
if ((ch == L'/' && Comment0()) || (ch == L'/' && Comment1())) return NextToken();
int recKind = noSym;
int recEnd = pos;
t = CreateToken();
t->pos = pos; t->col = col; t->line = line; t->charPos = charPos;
int state = start.state(ch);
tlen = 0; AddCh();
switch (state) {
case -1: { t->kind = eofSym; break; } // NextCh already done
case 0: {
case_0:
if (recKind != noSym) {
tlen = recEnd - t->pos;
SetScannerBehindT();
}
t->kind = recKind; break;
} // NextCh already done
case 1:
case_1:
recEnd = pos; recKind = 1;
if ((ch >= L'0' && ch <= L'9') || (ch >= L'A' && ch <= L'Z') || (ch >= L'a' && ch <= L'z')) {AddCh(); goto case_1;}
else {t->kind = 1; wchar_t *literal = coco_string_create(tval, 0, tlen); t->kind = keywords.get(literal, t->kind); coco_string_delete(literal); break;}
case 2:
case_2:
recEnd = pos; recKind = 2;
if ((ch >= L'0' && ch <= L'9')) {AddCh(); goto case_2;}
else {t->kind = 2; break;}
case 3:
case_3:
if ((ch >= L'A' && ch <= L'Z') || (ch >= L'a' && ch <= L'z')) {AddCh(); goto case_3;}
else if (ch == L'"') {AddCh(); goto case_4;}
else {goto case_0;}
case 4:
case_4:
{t->kind = 3; break;}
case 5:
- {t->kind = 6; break;}
+ {t->kind = 4; break;}
case 6:
- {t->kind = 7; break;}
+ {t->kind = 5; break;}
case 7:
- {t->kind = 8; break;}
+ {t->kind = 6; break;}
case 8:
- {t->kind = 9; break;}
+ {t->kind = 8; break;}
case 9:
- {t->kind = 10; break;}
+ {t->kind = 9; break;}
case 10:
- {t->kind = 11; break;}
+ case_10:
+ {t->kind = 10; break;}
case 11:
- {t->kind = 12; break;}
+ {t->kind = 11; break;}
case 12:
- {t->kind = 18; break;}
+ {t->kind = 12; break;}
case 13:
- {t->kind = 19; break;}
+ {t->kind = 13; break;}
case 14:
- {t->kind = 20; break;}
+ {t->kind = 19; break;}
case 15:
- {t->kind = 21; break;}
+ {t->kind = 20; break;}
case 16:
- {t->kind = 22; break;}
+ {t->kind = 29; break;}
case 17:
- {t->kind = 23; break;}
+ {t->kind = 30; break;}
case 18:
- case_18:
- {t->kind = 24; break;}
+ {t->kind = 31; break;}
case 19:
- {t->kind = 25; break;}
+ {t->kind = 32; break;}
case 20:
- {t->kind = 26; break;}
+ {t->kind = 33; break;}
case 21:
- recEnd = pos; recKind = 4;
- if (ch == L'=') {AddCh(); goto case_18;}
- else {t->kind = 4; break;}
+ recEnd = pos; recKind = 21;
+ if (ch == L'>') {AddCh(); goto case_10;}
+ else {t->kind = 21; break;}
}
AppendVal(t);
return t;
}
void Scanner::SetScannerBehindT() {
buffer->SetPos(t->pos);
NextCh();
line = t->line; col = t->col; charPos = t->charPos;
for (int i = 0; i < tlen; i++) NextCh();
}
// get the next token (possibly a token already seen during peeking)
Token* Scanner::Scan() {
if (tokens->next == NULL) {
return pt = tokens = NextToken();
} else {
pt = tokens = tokens->next;
return tokens;
}
}
// peek for the next token, ignore pragmas
Token* Scanner::Peek() {
do {
if (pt->next == NULL) {
pt->next = NextToken();
}
pt = pt->next;
} while (pt->kind > maxT); // skip pragmas
return pt;
}
// make sure that peeking starts at the current scan position
void Scanner::ResetPeek() {
pt = tokens;
}
diff --git a/coco/Scanner.h b/coco/Scanner.h
index a7bbe0d..9defd77 100644
--- a/coco/Scanner.h
+++ b/coco/Scanner.h
@@ -1,289 +1,289 @@
/*----------------------------------------------------------------------
Compiler Generator Coco/R,
Copyright (c) 1990, 2004 Hanspeter Moessenboeck, University of Linz
extended by M. Loeberbauer & A. Woess, Univ. of Linz
ported to C++ by Csaba Balazs, University of Szeged
with improvements by Pat Terry, Rhodes University
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
As an exception, it is allowed to write an extension of Coco/R that is
used as a plugin in non-free software.
If not otherwise stated, any source code generated by Coco/R (other than
Coco/R itself) does not fall under the GNU General Public License.
-----------------------------------------------------------------------*/
#if !defined(COCO_SCANNER_H__)
#define COCO_SCANNER_H__
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
// io.h and fcntl are used to ensure binary read from streams on windows
#if _MSC_VER >= 1300
#include <io.h>
#include <fcntl.h>
#endif
#if _MSC_VER >= 1400
#define coco_swprintf swprintf_s
#elif _MSC_VER >= 1300
#define coco_swprintf _snwprintf
#elif defined __MINGW32__
#define coco_swprintf _snwprintf
#else
// assume every other compiler knows swprintf
#define coco_swprintf swprintf
#endif
#define COCO_WCHAR_MAX 65535
-#define MIN_BUFFER_LENGTH 1024
-#define MAX_BUFFER_LENGTH (64*MIN_BUFFER_LENGTH)
-#define HEAP_BLOCK_SIZE (64*1024)
+#define COCO_MIN_BUFFER_LENGTH 1024
+#define COCO_MAX_BUFFER_LENGTH (64*COCO_MIN_BUFFER_LENGTH)
+#define COCO_HEAP_BLOCK_SIZE (64*1024)
#define COCO_CPP_NAMESPACE_SEPARATOR L':'
+
+
// string handling, wide character
wchar_t* coco_string_create(const wchar_t *value);
wchar_t* coco_string_create(const wchar_t *value, int startIndex);
wchar_t* coco_string_create(const wchar_t *value, int startIndex, int length);
wchar_t* coco_string_create_upper(const wchar_t* data);
wchar_t* coco_string_create_lower(const wchar_t* data);
wchar_t* coco_string_create_lower(const wchar_t* data, int startIndex, int dataLen);
wchar_t* coco_string_create_append(const wchar_t* data1, const wchar_t* data2);
wchar_t* coco_string_create_append(const wchar_t* data, const wchar_t value);
void coco_string_delete(wchar_t* &data);
int coco_string_length(const wchar_t* data);
bool coco_string_endswith(const wchar_t* data, const wchar_t *value);
int coco_string_indexof(const wchar_t* data, const wchar_t value);
int coco_string_lastindexof(const wchar_t* data, const wchar_t value);
void coco_string_merge(wchar_t* &data, const wchar_t* value);
bool coco_string_equal(const wchar_t* data1, const wchar_t* data2);
int coco_string_compareto(const wchar_t* data1, const wchar_t* data2);
int coco_string_hash(const wchar_t* data);
// string handling, ascii character
wchar_t* coco_string_create(const char *value);
char* coco_string_create_char(const wchar_t *value);
void coco_string_delete(char* &data);
-
-
class Token
{
public:
int kind; // token kind
int pos; // token position in bytes in the source text (starting at 0)
int charPos; // token position in characters in the source text (starting at 0)
int col; // token column (starting at 1)
int line; // token line (starting at 1)
wchar_t* val; // token value
Token *next; // ML 2005-03-11 Peek tokens are kept in linked list
Token();
~Token();
};
class Buffer {
// This Buffer supports the following cases:
// 1) seekable stream (file)
// a) whole stream in buffer
// b) part of stream in buffer
// 2) non seekable stream (network, console)
private:
unsigned char *buf; // input buffer
int bufCapacity; // capacity of buf
int bufStart; // position of first byte in buffer relative to input stream
int bufLen; // length of buffer
int fileLen; // length of input stream (may change if the stream is no file)
int bufPos; // current position in buffer
FILE* stream; // input stream (seekable)
bool isUserStream; // was the stream opened by the user?
int ReadNextStreamChunk();
bool CanSeek(); // true if stream can be seeked otherwise false
public:
static const int EoF = COCO_WCHAR_MAX + 1;
Buffer(FILE* s, bool isUserStream);
Buffer(const unsigned char* buf, int len);
Buffer(Buffer *b);
virtual ~Buffer();
virtual void Close();
virtual int Read();
virtual int Peek();
virtual wchar_t* GetString(int beg, int end);
virtual int GetPos();
virtual void SetPos(int value);
};
class UTF8Buffer : public Buffer {
public:
UTF8Buffer(Buffer *b) : Buffer(b) {};
virtual int Read();
};
//-----------------------------------------------------------------------------------
// StartStates -- maps characters to start states of tokens
//-----------------------------------------------------------------------------------
class StartStates {
private:
class Elem {
public:
int key, val;
Elem *next;
Elem(int key, int val) { this->key = key; this->val = val; next = NULL; }
};
Elem **tab;
public:
StartStates() { tab = new Elem*[128]; memset(tab, 0, 128 * sizeof(Elem*)); }
virtual ~StartStates() {
for (int i = 0; i < 128; ++i) {
Elem *e = tab[i];
while (e != NULL) {
Elem *next = e->next;
delete e;
e = next;
}
}
delete [] tab;
}
void set(int key, int val) {
Elem *e = new Elem(key, val);
int k = ((unsigned int) key) % 128;
e->next = tab[k]; tab[k] = e;
}
int state(int key) {
Elem *e = tab[((unsigned int) key) % 128];
while (e != NULL && e->key != key) e = e->next;
return e == NULL ? 0 : e->val;
}
};
//-------------------------------------------------------------------------------------------
// KeywordMap -- maps strings to integers (identifiers to keyword kinds)
//-------------------------------------------------------------------------------------------
class KeywordMap {
private:
class Elem {
public:
wchar_t *key;
int val;
Elem *next;
Elem(const wchar_t *key, int val) { this->key = coco_string_create(key); this->val = val; next = NULL; }
virtual ~Elem() { coco_string_delete(key); }
};
Elem **tab;
public:
KeywordMap() { tab = new Elem*[128]; memset(tab, 0, 128 * sizeof(Elem*)); }
virtual ~KeywordMap() {
for (int i = 0; i < 128; ++i) {
Elem *e = tab[i];
while (e != NULL) {
Elem *next = e->next;
delete e;
e = next;
}
}
delete [] tab;
}
void set(const wchar_t *key, int val) {
Elem *e = new Elem(key, val);
int k = coco_string_hash(key) % 128;
e->next = tab[k]; tab[k] = e;
}
int get(const wchar_t *key, int defaultVal) {
Elem *e = tab[coco_string_hash(key) % 128];
while (e != NULL && !coco_string_equal(e->key, key)) e = e->next;
return e == NULL ? defaultVal : e->val;
}
};
class Scanner {
private:
void *firstHeap;
void *heap;
void *heapTop;
void **heapEnd;
unsigned char EOL;
int eofSym;
int noSym;
int maxT;
int charSetSize;
StartStates start;
KeywordMap keywords;
Token *t; // current token
wchar_t *tval; // text of current token
int tvalLength; // length of text of current token
int tlen; // length of current token
Token *tokens; // list of tokens already peeked (first token is a dummy)
Token *pt; // current peek token
int ch; // current input character
int pos; // byte position of current character
int charPos; // position by unicode characters starting with 0
int line; // line number of current character
int col; // column number of current character
int oldEols; // EOLs that appeared in a comment;
void CreateHeapBlock();
Token* CreateToken();
void AppendVal(Token *t);
void SetScannerBehindT();
void Init();
void NextCh();
void AddCh();
bool Comment0();
bool Comment1();
Token* NextToken();
public:
Buffer *buffer; // scanner buffer
Scanner(const unsigned char* buf, int len);
Scanner(const wchar_t* fileName);
Scanner(FILE* s);
~Scanner();
Token* Scan();
Token* Peek();
void ResetPeek();
}; // end Scanner
#endif
diff --git a/coco/gen-xreate b/coco/gen-xreate
new file mode 100755
index 0000000..132dff9
--- /dev/null
+++ b/coco/gen-xreate
@@ -0,0 +1 @@
+cococpp -frames /usr/share/coco-cpp/ ./xreate.ATG
diff --git a/coco/xreate.ATG b/coco/xreate.ATG
index ff3cf75..ed7e702 100644
--- a/coco/xreate.ATG
+++ b/coco/xreate.ATG
@@ -1,118 +1,198 @@
#include "ast.h"
#include <string>
COMPILER Xreate
AST root; // current program unit (procedure or main program)
+bool checkParametersList()
+{
+ scanner.ResetPeek();
+ Token x = scanner->Peek();
+ return la->kind == _ident && x->kind == _lparen;
+}
+
+bool checkInfix()
+{
+ scanner.ResetPeek();
+ Token x = scanner->Peek();
+ return la->kind == _ident && x->kind == _ident;
+}
+
+bool check
+
CHARACTERS
letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".
digit = "0123456789".
cr = '\r'.
lf = '\n'.
tab = '\t'.
TOKENS
ident = letter {letter | digit}.
number = digit {digit}.
string = '"' {letter} '"'.
+ lparen = '('.
+ rparen = ')'.
COMMENTS FROM "/*" TO "*/" NESTED
COMMENTS FROM "//" TO lf
IGNORE cr + lf + tab
PRODUCTIONS
-
-Xreate = {FDecl}.
+Xreate = { ( FDecl | RuleDecl ) }.
Ident<std::wstring& name>
= ident (. name = t->val; .).
FDecl<> = (. std::wstring fname; Expression fbody; std::wstring varname; TypeAnnotation typIn; TypeAnnotation typOut; .)
Ident<fname> '=' "function" ':' (. Function f = Function(fname); .)
( Type<typOut> (. f.setReturnType(typOut); .)
| '('Ident<varname> ':' Type<typIn> (. f.addArg(varname, typIn); .)
{',' Ident<varname> ':' Type<typIn> (. f.addArg(varname, typIn);.)
-} ')' )
-
-'{' {VDecl<f> ';' }
-Expr<fbody> '}' (. f.setBody(fbody); .) .
+} ')' "->" Type<typOut> (. f.setReturnType(typOut); .)
+{',' FnTag<f> }
+) '{' {VDecl<f> ';' }
+Expr<fbody> ';' '}' (. f.setBody(fbody); root.add(f); .) .
TypeTerm<TypeAtom& typ> = ("string" | "int" | "num" | "float" | "bool") (. typ = Atom<Type_t>(t->val); .) .
Type<TypeAnnotation& typ> = (. TypeAnnotation typ2; TypeAtom typ3; .)
('[' Type<typ2> ']' (. typ = TypeAnnotation(TypeOperator::LIST, typ2); .)
| TypeTerm<typ3> (. typ = TypeAnnotation(typ3); .)
) .
VDecl<Function& f> = (. std::wstring vname; Expression e; TypeAnnotation typ; .)
Ident<vname> '='
(Expr<e> ':' Type<typ> (. f.addDeclaration(vname, typ, e); .)
|ListLiteral<e> ':' Type<typ> (. f.addListDeclaration(vname, typ, e); .)
-) ';'.
+).
+ /*============================ METAPROGRAMMING ===============================*/
+
+FnTag<Function& f> = (.std::wstring tag; TagModifier mod = TagModifier::NONE; .)
+Ident<tag>
+['-' TagMod<mod>] (. f.addTag(tag, mod); .).
+
+TagMod<TagModifier& mod> =
+( "assert" (. mod = TagModifier::ASSERT; .)
+ | "require" (. mod = TagModifier::REQUIRE; .)
+).
+
+RuleDecl<> =
+"rule" ':' (. RuleArguments args; RuleGuards guards; RuleBody body; DomainAnnotation typ; .)
+'(' Ident<arg> ':' Domain<typ> (. args.add(arg, typ); .)
+{',' Ident<arg> ':'Domain<typ> (. args.add(arg, typ); .)
+} ')'
+["case" RGuard<guards> {',' RGuard<guards>}]
+ (. .)
+'{' RBody<args, guards> '}' .
+
+Domain<DomainAnnotation& dom> =
+(
+ "function" (. dom = DomainAnnotation::FUNCTION; .)
+ | "variable" (. dom = DomainAnnotation::VARIABLE; .)
+).
+
+RGuard<RuleGuards& guards>= (. MetaExpression e; .)
+MetaExpr<e> (. guards.add(e); .).
+
+MetaExpr<MetaExpression& e>=
+MetaExpr2<e>
+[MetaOp<op> MetaExpr2<e2> (. MetaParameters params;
+ params.add(e);
+ params.add(e2);
+ e = MetaExpression(op, params); .)
+].
+
+MetaExpr2<MetaExpression& e>= (. std::wstring i1, i2, infix; MetaParameters params; .)
+( IF(checkParametersList()) Ident<i1> '(' [ MetaParams<params> ] ')'
+ (. e = MetaExpression(Operator::CALL, i1, params); .)
+| IF(checkInfix()) Ident<i1> Ident<infix> Ident<i2>
+ (. params.add(Expression(Atom<Identifier_t>(i1->val)));
+ params.add(Expression(Atom<Identifier_t>(i2->val)));
+ e = MetaExpression(Operator::CALL, Atom<Identifier_t>(infix->val), params); .)
+| Ident<i1> (. e = MetaExpression(Atom<Identifier_t>(i1->val)); .)
+| '(' MetaExpr<e> ')'
+).
+
+MetaParams<MetaParameters& params> = (. MetaExpr e; .)
+MetaExpr<e> (. params.add(e); .)
+{',' MetaExpr<e> (. params.add(e).)
+}.
+
+RBody<RuleBody& body> = (. MetaExpr e; .)
+ "warning" MetaExpr<e> ["message" string] .
+
+MetaOp< Operator& op> =
+ '-' '>' (. op = OPERATOR::IMPL; .)
+.
+
+
+
-ListLiteral<Expression& e> = (. Expression e2; .)
-'['
-(']' ';' (. e = Expression(Operator::LIST, Expression()); .)
-| Expr<e2> (. e = Expression(Operator::LIST, e2); .)
-{',' Expr<e2> (. e.addArg(e2); .)
-}
-']'
-';').
/*============================ Expressions ===============================*/
+ListLiteral<Expression& e> = (. Expression e2; .)
+'[' (. e = Expression(Operator::LIST, Expression()); .)
+[ Expr<e2> (. e.addArg(e2); .)
+{',' Expr<e2> (. e.addArg(e2); .)
+}] ']'.
+
+
Expr< Expression& e> (. Operator op; Expression e2; .)
= SimExpr< e>
[ RelOp< op>
- SimExpr< e2> (. Expression e (op, e);
- e.addArg(e2);
- .)
+ SimExpr< e2> (. e = Expression(op, e); e.addArg(e2); .)
].
SimExpr< Expression& e> (. Operator op; Expression e2; .)
= Term< e>
{ AddOp< op>
- Term< e2> (. e = Expression(op, e);
- e.addArg(e2);
- .)
+ Term< e2> (. e = Expression(op, e); e.addArg(e2);.)
}.
Term< Expression& e> (. Operator op; Expression e2; .)
= Factor< e>
{ MulOp< op>
- Factor< e2> (. e = Expression(op, e);
- e.addArg(e2);
- .)
- }.
+ Factor< e2> (. e = Expression(op, e); e.addArg(e2); .)
+ }.
-Factor< Expression& e> (. std::wstring name; .)
+Factor< Expression& e> (. std::wstring name;.)
=
- ( Ident< name> (. e = Expression(Atom<Identifier_t>(name)); .)
- | number (. e = Expression(Atom<Number_t>(t->val)); .)
- | '-' Factor< e> (. e = Expression(Operator::NEG, e); .)
+ (IF (checkParametersList()) Ident< name>
+ (. e = Expression(Operator::CALL, Atom<Identifier_t>(name)); .)
+ '(' [CalleeParams<e>] ')'
+ | Ident< name> (. e = Expression(Atom<Identifier_t>(name)); .)
+
+ | number (. e = Expression(Atom<Number_t>(t->val)); .)
+ | '-' Factor< e> (. e = Expression(Operator::NEG, e); .)
+ | '(' Expr<e> ')'
).
-
+CalleeParams<Expression& e> = (. Expression e2; .)
+ Expr<e2> (. e.addArg(e2); .)
+ {',' Expr<e2> (. e.addArg(e2); .)
+ }.
AddOp< Operator& op>
= (. op = Operator::ADD; .)
( '+'
| '-' (. op = Operator::SUB; .)
).
MulOp< Operator& op>
= (. op = Operator::MUL; .)
( '*'
| '/' (. op = Operator::DIV; .)
).
RelOp< Operator& op>
= (. op = Operator::EQU; .)
- ( "=="
+ ( '=' '='
| '<' (. op = Operator::LSS; .)
| '>' (. op = Operator::GTR; .)
).
END Xreate.
diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt
new file mode 100644
index 0000000..58c7116
--- /dev/null
+++ b/cpp/CMakeLists.txt
@@ -0,0 +1,68 @@
+cmake_minimum_required(VERSION 2.8.11)
+project(Xreate)
+find_package(LLVM REQUIRED CONFIG)
+find_package(Qt5Core)
+
+message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
+message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+
+set(SOURCE_FILES
+ ./src/ast.cpp ./src/ast-compilation.cpp
+ ./src/llvmlayer.cpp ./src/clasplayer.cpp
+ #./src/main.cpp
+ ./tests/tests.cpp
+ ./src/pass/cfgpass.cpp ./src/pass/functiontagspass.cpp
+
+ /opt/potassco/gringo-4.4.0-source/app/shared/src/clingocontrol.cc
+ /opt/potassco/gringo-4.4.0-source/app/pyclingo/src/clingo_lib.cc
+)
+
+set(COCO_PATH "./../coco/")
+set(COCO_SOURCE_FILES
+ ${COCO_PATH}/Parser.h
+ ${COCO_PATH}/Scanner.h
+ ${COCO_PATH}/Parser.cpp
+ ${COCO_PATH}/Scanner.cpp
+)
+
+set(POTASSCO_PATH "/opt/potassco/gringo-4.4.0-source")
+
+INCLUDE_DIRECTORIES(${COCO_PATH} ./src)
+INCLUDE_DIRECTORIES(${POTASSCO_PATH}/libgringo
+${POTASSCO_PATH}/libclasp
+${POTASSCO_PATH}/app/shared/include
+${POTASSCO_PATH}/app/pyclingo/src
+${POTASSCO_PATH}/libprogram_opts
+)
+
+execute_process(COMMAND ${COCO_PATH}/gen-xreate WORKING_DIRECTORY ${COCO_PATH} OUTPUT_VARIABLE COCO_OUTPUT)
+message(STATUS "COCO GRAMMAR BUILD STATUS:" ${COCO_OUTPUT})
+
+include_directories(${LLVM_INCLUDE_DIRS})
+add_definitions(${LLVM_DEFINITIONS})
+
+add_executable(xreate ${SOURCE_FILES} ${COCO_SOURCE_FILES})
+
+llvm_map_components_to_libnames(llvm_libs support core irreader)
+message(STATUS "LLVM LIBS: " ${llvm_libs})
+
+set (LIBCLASP_PATH ${POTASSCO_PATH}/build/debug)
+
+#find_library(LIBCLASP_LIBRARY_GRINGO NAMES gringo
+# HINTS ${LIBCLASP_PATH})
+#find_library(LIBCLASP_LIBRARY_CLASP NAMES clasp
+# HINTS ${LIBCLASP_PATH})
+
+set(LIBCLASP_LIBS
+ ${LIBCLASP_PATH}/libclasp.a
+ ${LIBCLASP_PATH}/libgringo.a
+ ${LIBCLASP_PATH}/libprogram_opts.a
+)
+
+message(STATUS ${LIBCLASP_LIBS})
+
+target_link_libraries(xreate ${llvm_libs} pthread Qt5::Core ${LIBCLASP_LIBS})
+
+add_definitions(-DWITH_THREADS=0)
diff --git a/cpp/src/ast-compilation.cpp b/cpp/src/ast-compilation.cpp
new file mode 100644
index 0000000..118252a
--- /dev/null
+++ b/cpp/src/ast-compilation.cpp
@@ -0,0 +1,168 @@
+#include <ast.h>
+
+llvm::Value*
+LLVMExpression::compile(LLVMLayer& l, Function* f, std::string* hintRetVar) const
+{
+ std::string var;
+ if (hintRetVar && f->__vartable.count(*hintRetVar))
+ {
+ var = *hintRetVar;
+ }
+
+ #define VARNAME(x) (var.size()? var : x)
+ llvm::Value* left; llvm::Value* right;
+
+
+ switch (__op)
+ {
+ case Operator::ADD: case Operator::SUB: case Operator::MUL: case Operator::DIV: case Operator::EQU: case Operator::LSS: case Operator::GTR:
+ assert(__source.__state == COMPOUND);
+ assert(__source.operands.size() == 2);
+
+ left = __source.operands[0].compile(l, f);
+ right = __source.operands[1].compile(l, f);
+ break;
+
+ default: ;
+ }
+
+ switch (__op)
+ {
+ case Operator::ADD:
+ return l.builder.CreateFAdd(left, right, VARNAME("tmp_add"));
+ break;
+
+ case Operator::SUB:
+ return l.builder.CreateFSub(left, right, VARNAME("tmp_sub"));
+ break;
+
+ case Operator::MUL:
+ return l.builder.CreateFMul(left, right, VARNAME("tmp_mul"));
+ break;
+
+ case Operator::DIV:
+ return l.builder.CreateFDiv(left, right, VARNAME("tmp_div"));
+ break;
+
+ case Operator::EQU:
+ return l.builder.CreateFCmpOEQ(left, right, VARNAME("tmp_equ"));
+ break;
+
+ case Operator::LSS:
+ return l.builder.CreateFCmpOLT(left, right, VARNAME("tmp_lss"));
+ break;
+
+ case Operator::GTR:
+ return l.builder.CreateFCmpOGT(left, right, VARNAME("tmp_gtr"));
+ break;
+
+ case Operator::NEG:
+ left = __source.operands[0].compile(l, f);
+ return l.builder.CreateFNeg(left, VARNAME("tmp_neg"));
+ break;
+
+ case Operator::CALL:
+ {
+ assert(__source.__state == COMPOUND);
+
+ const std::string& fname = __source.__valueS;
+ assert(f->root->__indexFunctions.count(fname));
+
+ const Function& calleeFunc = f->root->getFunctionById(f->root->__indexFunctions[fname]);
+ llvm::Function* callee = calleeFunc.__raw;
+
+ std::vector<llvm::Value*> args;
+ args.reserve(operands.size()-1);
+
+ std::transform(__source.operands.begin(), __source.operands.end(), std::inserter(args, args.end()),
+ [&l, f](const Expression &operand){return compile(operand, f); }
+ );
+
+ return l.builder.CreateCall(callee, args, VARNAME("tmp_call"));
+ }
+ break;
+
+
+ case Operator::NONE:
+ assert(__source.__state != COMPOUND);
+
+ switch (__source.__state)
+ {
+ case IDENT:
+ {
+ std::string vname = __source.__valueS;
+ assert(f->__vartable.count(vname));
+
+ VID vId =f->__vartable[vname];
+ if (f->__rawVars.count(vId))
+ {
+ return f->__rawVars[vId];
+ }
+
+ Expression& e = f->__declarations[vId];
+ llvm::Value* result = e.compile(l, f, &vname);
+ f->__rawVars[vId] = result;
+ return result;
+ break;
+ }
+
+ case NUMBER:
+ double literal = __valueD;
+ return llvm::ConstantFP::get(llvm::getGlobalContext(), llvm::APFloat(literal));
+ };
+
+ break;
+
+ }
+
+ assert(false);
+ return 0;
+}
+
+llvm::Function*
+Function::compile(LLVMLayer &l)
+{
+
+ std::vector<llvm::Type*> types;
+ std::transform(__args.begin(), __args.end(), std::inserter(types, types.end()),
+ [this](std::string& arg) {
+ assert(__vartable.count(arg));
+ VID argid = __vartable[arg];
+
+ assert(__definitions.count(argid));
+ return __definitions[argid].toLLVMType();
+ } );
+
+ llvm::FunctionType* ft = llvm::FunctionType::get(__retType.toLLVMType(), types,false);
+ __raw = llvm::cast<llvm::Function>(l.module->getOrInsertFunction(__name,ft));
+
+ llvm::Function::arg_iterator fargsI = __raw->arg_begin();
+ for(std::string& arg : __args)
+ {
+ VID argid = __vartable[arg];
+
+ __rawVars[argid] = fargsI;
+ fargsI->setName(arg);
+ ++fargsI;
+ }
+
+ llvm::BasicBlock *block = llvm::BasicBlock::Create(llvm::getGlobalContext(), "entry", __raw);
+ l.builder.SetInsertPoint(block);
+
+ l.builder.CreateRet(__body.compile(l, this, 0));
+ l.moveToGarbage(ft);
+
+ return __raw;
+};
+
+void
+AST::compile(LLVMLayer &layer)
+{
+ layer.module = new llvm::Module(getModuleName(),llvm::getGlobalContext());
+
+ for(Function& f: __functions)
+ {
+ llvm::Function* rawf = f.compile(layer);
+
+ }
+}
diff --git a/cpp/src/ast.cpp b/cpp/src/ast.cpp
index f4b6f97..fcc157f 100644
--- a/cpp/src/ast.cpp
+++ b/cpp/src/ast.cpp
@@ -1,305 +1,236 @@
#include "ast.h"
#include <stdexcept>
+#include <iostream>
+#include <QString>
+#include <clasplayer.h>
+
using namespace std;
TypeAnnotation::TypeAnnotation()
{}
TypeAnnotation::TypeAnnotation(const Atom<Type_t> &typ)
{
__value = typ.get();
}
TypeAnnotation::TypeAnnotation(const TypeOperator &op, const TypeAnnotation &typ)
{}
llvm::Type*
TypeAnnotation::toLLVMType()
{
switch (__value)
{
case Bool:
return llvm::Type::getInt1Ty(llvm::getGlobalContext());
case Int:
case Float:
case Num:
return llvm::Type::getDoubleTy(llvm::getGlobalContext());
default:
assert(false);
}
return NULL;
}
-Expression::Expression()
- : __op(Operator::NONE), state(INVALID)
-{}
+
Expression::Expression(const Atom<Number_t>& number)
-: state(NUMBER), __op(Operator::NONE), __valueD(number.get())
+: __state(NUMBER), __op(Operator::NONE), __valueD(number.get())
{
}
Expression::Expression(const Atom<Identifier_t> &ident)
- : state(IDENT), __op(Operator::NONE), __valueS(ident.get())
+ : __state(IDENT), __op(Operator::NONE), __valueS(ident.get())
{
}
-Expression::Expression(const Operator &op, const Expression &arg)
- : state(COMPOUND), __op(op)
+Expression::Expression(const Operator &op, std::initializer_list<Expression> params)
+ : __state(COMPOUND), __op(op)
{
- operands.push_back(arg);
-}
+ if (op == Operator::CALL)
+ {
+ assert(params.size() > 0);
+ Expression arg = *params.begin();
-void
-Expression::addArg(const Expression &arg)
-{
- assert(state == COMPOUND);
- assert(op!=Operator::NONE);
+ assert(arg.__state == Expression::IDENT);
+ __valueS = std::move(arg.__valueS);
+ return;
+ }
- operands.push_back(arg);
+ operands.insert(operands.end(), params);
}
-llvm::Value*
-Expression::compile(LLVMLayer& l, Function* f, std::string* retVarHint)
+void
+Expression::setOp(Operator op)
{
- std::string var;
- if (retVarHint && f->__vartable.count(*retVarHint))
- {
- var = *retVarHint;
- }
-
- #define VARNAME(x) (var.size()? var : x)
- llvm::Value* left; llvm::Value* right;
+ __op = op;
-
- switch (__op)
+ switch (op)
{
- case Operator::ADD: case Operator::SUB: case Operator::MUL: case Operator::DIV: case Operator::EQU: case Operator::LSS: case Operator::GTR:
- left = operands[0].compile(l, f);
- right = operands[1].compile(l, f);
+ case Operator::NONE:
+ __state = INVALID;
break;
- default: ;
- }
-
- switch (__op)
- {
- case Operator::ADD:
- return l.builder.CreateFAdd(left, right, VARNAME("tmp_add"));
- break;
-
- case Operator::SUB:
- return l.builder.CreateFSub(left, right, VARNAME("tmp_sub"));
- break;
-
- case Operator::MUL:
- return l.builder.CreateFMul(left, right, VARNAME("tmp_add"));
- break;
-
- case Operator::DIV:
- return l.builder.CreateFDiv(left, right, VARNAME("tmp_sub"));
- break;
-
- case Operator::EQU:
- return l.builder.CreateFCmpOEQ(left, right, VARNAME("tmp_eq"));
- break;
-
- case Operator::LSS:
- return l.builder.CreateFCmpOLT(left, right, VARNAME("tmp_eq"));
- break;
-
- case Operator::GTR:
- return l.builder.CreateFCmpOGT(left, right, VARNAME("tmp_eq"));
- break;
-
- case Operator::NEG:
- left = operands[0].compile(l, f);
- return l.builder.CreateFNeg(left, VARNAME("tmp_eq"));
- break;
-
- case Operator::CALL:
- {
- std::string fname = operands[0].__valueS;
- assert(f->root->__rawFunctions.count(fname));
-
- llvm::Function* callee = f->root->__rawFunctions[fname];
-
- std::vector<llvm::Value*> args;
- args.reserve(operands.size()-1);
- for(int i=1; i<operands.size(); ++i)
- {
- args.push_back(operands[i].compile(l, f));
- }
-
- return l.builder.CreateCall(callee, args, VARNAME("tmp_call"));
- }
- break;
-
-
- case Operator::NONE:
- switch (state)
- {
- case IDENT:
- {
- std::string vname = operands[0].__valueS;
- assert(f->__vartable.count(vname));
-
- vid vId =f->__vartable[vname];
-
- assert(var.size()==0);
- if (f->__rawVars.count(vId))
- {
- return f->__rawVars[vId];
- }
-
- Expression& e = f->__declarations[vId];
- llvm::Value* result = e.compile(l, f);
- f->__rawVars[vId] = result;
- return result;
+ default:
+ __state = COMPOUND;
break;
- }
+ }
+}
- case NUMBER:
- double literal = operands[0].__valueD;
- return llvm::ConstantFP::get(llvm::getGlobalContext(), llvm::APFloat(literal));
- };
+void
+Expression::addArg(Expression &&arg)
+{
+ operands.push_back(arg);
+}
- break;
+Expression::Expression()
+ : __op(Operator::NONE), __state(INVALID)
+{}
- }
- assert(false);
- return 0;
+AST::AST()
+{
}
-AST::AST()
+void
+AST::add(Function &f)
{
+ f.root = this;
+ __functions.push_back(f);
+ __indexFunctions[f.getName()] = __functions.size()-1;
}
std::string
AST::getModuleName()
{
const std::string name = "moduleTest";
return name;
}
-void
-AST::compile(LLVMLayer &layer)
+FID
+AST::getFunctionsCount() const
{
- layer.module = new llvm::Module(getModuleName(),llvm::getGlobalContext());
+ return __functions.size();
+}
- for(Function& f: __functions)
- {
- llvm::Function* rawf = f.compile(layer);
- __rawFunctions[f.getName()] = rawf;
- }
+const Function&
+AST::getFunctionById(FID id)const
+{
+ assert(id>=0 && id < __functions.size());
+ return __functions[id];
}
void
AST::run(LLVMLayer &l)
{
llvm::PassManager PM;
- PM.add(llvm::createPrintModulePass(&llvm::outs()));
+ PM.add(llvm::createPrintModulePass(llvm::outs()));
PM.run(*l.module);
}
Function::Function(const wstring &name)
+ :__vCounter(0)
{
char buffer[1000];
wcstombs(buffer, name.c_str(), 1000);
__name = buffer;
}
+void
+Function::addAnnotation(const wstring& aname, const AnnotationModifier amod)
+{
+ char buffer[1000];
+ wcstombs(buffer, aname.c_str(), 1000);
+ std::string name(buffer);
+
+ cout << QString("Function annotation: %1 <- %2").arg(__name.c_str()).arg(name.c_str()).toStdString()<<endl;
+ __tags.push_back(std::make_pair(name, amod));
+}
+
+const std::vector<std::pair<std::string, AnnotationModifier>>&
+Function::getAnnotations() const
+{
+ return __tags;
+}
+
void
Function::addArg(const wstring &vname, const TypeAnnotation &typ)
{
char buffer[1000];
wcstombs(buffer, vname.c_str(), 1000);
std::string name(buffer);
- vid id = registerVar(name);
+ VID id = registerVar(name);
__definitions[id] = typ;
__args.push_back(name);
}
void
Function::setBody(const Expression &body)
{
__body = body;
}
void
Function::setReturnType(const TypeAnnotation &rtyp)
{
__retType = rtyp;
}
-vid
+VID
Function::registerVar(const std::string& vname)
{
- return ++__vCounter;
+ __vartable[vname] = ++__vCounter;
+ return __vCounter;
}
const std::string&
Function::getName() const
{
return __name;
}
void
Function::addListDeclaration(const wstring &vname, const TypeAnnotation &typ, const Expression &e)
{}
void
Function::addDeclaration(const wstring &vname, const TypeAnnotation &typ, const Expression &e)
{
char buffer[1000];
wcstombs(buffer, vname.c_str(), 1000);
std::string v(buffer);
- vid id = registerVar(v);
+ VID id = registerVar(v);
__definitions[id] = typ;
__declarations[id] = e;
}
-llvm::Function*
-Function::compile(LLVMLayer &l)
-{
-
- std::vector<llvm::Type*> types;
- std::transform(__args.begin(), __args.end(), std::inserter(types, types.end()),
- [this](std::string& arg) {
- assert(__vartable.count(arg));
-
- vid argid = __vartable[arg];
- assert(__definitions.count(argid));
- return __definitions[argid].toLLVMType();
- } );
- llvm::FunctionType* ft = llvm::FunctionType::get(__retType.toLLVMType(), types,false);
- __raw = llvm::cast<llvm::Function>(l.module->getOrInsertFunction(__name,ft));
-
- llvm::Function::arg_iterator fargsI = __raw->arg_begin();
- for(std::string& arg : __args)
- {
- vid argid = __vartable[arg];
+void
+RuleArguments::add(std::string&& name, DomainAnnotation typ)
+{
+ emplace_back(name, typ);
+}
- __rawVars[argid] = fargsI;
- fargsI->setName(arg);
- ++fargsI;
- }
+void
+RuleGuards::add(Expression&& e)
+{
+ push_back(e);
+}
- llvm::BasicBlock *block = llvm::BasicBlock::Create(llvm::getGlobalContext(), "entry", __raw);
- l.builder.SetInsertPoint(block);
+void
+RuleWarning::compile(ClaspLayer& layer)
+{
+ layer.addRuleWarning(this);
+}
- l.builder.CreateRet(__body.compile(l, this, 0));
- l.moveToGarbage(ft);
- return __raw;
-};
diff --git a/cpp/src/ast.h b/cpp/src/ast.h
index 6e648c9..22b8597 100644
--- a/cpp/src/ast.h
+++ b/cpp/src/ast.h
@@ -1,189 +1,248 @@
#ifndef AST_H
#define AST_H
#include <vector>
#include <stdlib.h>
#include <string>
#include "llvmlayer.h"
struct Identifier_t {};
struct Number_t {};
struct Type_t {};
template<typename A>
class Atom{
};
template<> class Atom<Identifier_t>
{
public:
Atom(const std::wstring& value)
{
char buffer[1000];
wcstombs(buffer, value.c_str(), 1000);
__value = buffer;
}
const std::string& get() const{return __value; }
private:
std::string __value;
};
template<> class Atom<Number_t>
{
public:
Atom(wchar_t* value)
{
__value = wcstol(value, 0, 10);
}
int get()const {return __value; }
private:
double __value;
};
enum TimePrimitive {Bool, Int, Float, Num, String};
template<> class Atom<Type_t>
{
public:
Atom(wchar_t* value)
{
char buffer_[1000];
wcstombs(buffer_, value, 1000);
std::string buffer(buffer_);
if (buffer=="bool"){
__value = Bool;
} else if (buffer=="int") {
__value = Int;
} else if (buffer=="float") {
__value = Float;
} else if (buffer=="num") {
__value = Num;
} else if (buffer=="string") {
__value = String;
}
}
Atom ()
{
}
TimePrimitive get() const
{
return __value;
}
private:
TimePrimitive __value;
};
typedef Atom<Type_t> TypeAtom;
enum class TypeOperator{LIST};
class TypeAnnotation
{
public:
TypeAnnotation (const Atom<Type_t>& typ);
TypeAnnotation (const TypeOperator& op, const TypeAnnotation& typ);
TypeAnnotation();
llvm::Type* toLLVMType();
private:
TimePrimitive __value;
};
-
enum class Operator
{
-ADD, SUB, MUL, DIV, EQU, LSS, GTR, NEG, LIST, CALL, NONE
+ADD, SUB, MUL, DIV, EQU, LSS, GTR, NEG, LIST, CALL, NONE, IMPL/* implication */
};
-
class Function;
class AST;
-typedef unsigned int vid;
-
class Expression
{
public:
- Expression(const Operator& op, const Expression& arg);
+ Expression(const Operator &op, std::initializer_list<Expression> params);
Expression(const Atom<Identifier_t>& ident);
Expression(const Atom<Number_t>& number);
Expression();
- void addArg(const Expression& arg);
- llvm::Value* compile(LLVMLayer& l, Function* f, std::string* retVarHint=0);
-
-private:
+ void setOp(Operator op);
+ void addArg(Expression&& arg);
+protected:
Operator __op;
std::vector<Expression> operands;
std::string __valueS;
double __valueD;
- enum {INVALID, COMPOUND, IDENT, NUMBER, STRING} state;
+ enum {INVALID, COMPOUND, IDENT, NUMBER, STRING} __state;
+};
+
+enum class AnnotationModifier
+{NONE, ASSERT, REQUIRE};
+
+enum class DomainAnnotation
+{FUNCTION, VARIABLE};
+
+class RuleArguments: public std::vector<std::pair<std::string, DomainAnnotation>>
+{
+public:
+ void add(std::string&& name, DomainAnnotation typ);
+};
+
+class RuleGuards: public std::vector<Expression>
+{
+public:
+ void add(Expression&& e);
+};
+
+class MetaRuleAbstract
+{
+protected:
+ RuleArguments __args;
+ RuleGuards __guards;
+};
+
+class ClaspLayer;
+class RuleWarning: public MetaRuleAbstract
+{
+ friend class ClaspLayer;
+public:
+ void compile(ClaspLayer& layer);
+
+private:
+ std::string __message;
+ Expression __condition;
+};
+
+typedef unsigned int VID;
+
+
+
+/*
+class Expression: ExpressionAbstract
+{
+ friend class CFGPass;
+
+public:
+ llvm::Value* compile(LLVMLayer& l, Function* f, std::string* hintRetVar=0) const;
};
+*/
-typedef std::pair<vid, TypeAnnotation> VariableDefinition;
-typedef std::pair<vid, Expression> VariableDeclaration;
+typedef std::pair<VID, TypeAnnotation> VariableDefinition;
+typedef std::pair<VID, Expression> VariableDeclaration;
class Function
{
friend class Expression;
+ friend class CFGPass;
public:
Function(const std::wstring& name);
void setReturnType(const TypeAnnotation& rtyp);
void addArg(const std::wstring& vname, const TypeAnnotation& typ);
void setBody(const Expression& body);
+ void addAnnotation(const std::wstring& aname, const AnnotationModifier amod);
+ const std::vector<std::pair<std::string, AnnotationModifier>>& getAnnotations() const;
+
void addDeclaration(const std::wstring& vname, const TypeAnnotation& typ, const Expression& e);
void addListDeclaration(const std::wstring& vname, const TypeAnnotation& typ, const Expression& e);
const std::string& getName() const;
llvm::Function* compile(LLVMLayer& l);
-private:
AST* root;
+private:
+
std::string __name;
TypeAnnotation __retType;
std::vector<std::string> __args;
+ std::vector<std::pair<std::string, AnnotationModifier>> __tags;
std::map<VariableDefinition::first_type, VariableDefinition::second_type> __definitions;
std::map<VariableDeclaration::first_type, VariableDeclaration::second_type> __declarations;
- std::map<std::string, vid> __vartable;
+ std::map<std::string, VID> __vartable;
Expression __body;
llvm::Function* __raw;
- std::map<vid,llvm::Value*> __rawVars;
+ std::map<VID,llvm::Value*> __rawVars;
+
+ VID __vCounter;
- vid __vCounter;
+ VID registerVar(const std::string& vname);
- vid registerVar(const std::string& vname);
+ llvm::Value* compileExpression(Expression& expr, LLVMLayer& l, std::string* hintRetVar) const;
};
+typedef unsigned int FID;
class AST
{
friend class Expression;
+ friend class CFGPass;
+
public:
AST();
- void add(const Function& f);
+ void add(Function& f);
void compile(LLVMLayer& l);
void run(LLVMLayer& l);
std::string getModuleName();
+
+ FID getFunctionsCount() const;
+ const Function& getFunctionById(FID id) const;
private:
std::vector<Function> __functions;
-
- std::map<std::string, llvm::Function*> __rawFunctions;
+ std::map<std::string, FID> __indexFunctions;
};
#endif // AST_H
diff --git a/cpp/src/clasplayer.cpp b/cpp/src/clasplayer.cpp
new file mode 100644
index 0000000..a657703
--- /dev/null
+++ b/cpp/src/clasplayer.cpp
@@ -0,0 +1,276 @@
+#include "clasplayer.h"
+
+#include <clasp/program_builder.h> // for defining logic programs
+#include <clasp/unfounded_check.h> // unfounded set checkers
+#include <clasp/model_enumerators.h> // for enumerating answer sets
+#include <clasp/clasp_facade.h>
+
+#include <clingocontrol.hh>
+
+#include <iostream>
+#include <clingo_lib.hh>
+#include <QString>
+#include <QStringList>
+using namespace std;
+
+bool
+ClaspLayer::onModel(Gringo::Model const & model)
+{
+ cout << "Model: " << endl;
+ for (Gringo::Value atom : model.atoms(Gringo::Model::ATOMS))
+ {
+ atom.print(cout);
+ cout << endl;
+ }
+}
+
+QStringList multiplyLists(std::list<QStringList>&& lists)
+{
+ QStringList&& result = lists.front();
+ lists.pop_front();
+
+ for (QStringList& list: lists)
+ {
+ QStringList::const_iterator end = result.end();
+ for (QStringList::iterator expr1I=result.begin(); expr1I<end; ++expr1I)
+ {
+ if (list.size() == 0 ) continue;
+
+ StringList::const_iterator expr2I=list.begin();
+ for(int expr2No=0, size = list.size()-1; expr2No < size; ++expr2No, ++expr1I)
+ result.append(QString("%1, %2").arg(*expr1I).arg(*expr2I));
+
+ *expr1I = QString("%1, %2").arg(*expr1I).arg(*expr2I);
+ }
+ }
+
+ return result;
+}
+
+void
+ClaspLayer::addCFGData(CFGraph &&graph)
+{
+ ostream& cout = __partGeneral;
+
+ cout <<endl<< "%\t\tStatic analysis: CFG" << endl;
+
+ for (const std::pair<FID, FID>& relation: graph.__relations)
+ {
+ const string& tagFrom = graph.__nodes.at(relation.first);
+ const string& tagTo = graph.__nodes.at(relation.second);
+
+ cout << (QString("call(%1, %2) .").arg(tagFrom.c_str()).arg(tagTo.c_str())).toStdString()<<endl;
+ }
+}
+
+void
+ClaspLayer::addFunctionTags(const std::string& function, const std::vector<Tag>& tags)
+{
+ ostream& cout = __partTags;
+
+ cout << (QString("function(%1) .").arg(function.c_str())).toStdString()<<std::endl;
+
+ int tagsCount=0;
+ for(Tag tag: tags)
+ {
+ cout << QString("tag(%1, %2).").arg(function.c_str()).arg(tag.first.c_str()).toStdString() << endl;
+ ++tagsCount;
+ }
+ if (tagsCount == 0)
+ {
+ cout << "%no tags at all" << endl;
+ }
+}
+
+void
+ClaspLayer::addRuleWarning(RuleWarning* rule)
+{
+ //__partGeneral << rule << endl;
+
+ std::QStringList domains;
+ std::transform(rule->__args.begin(), rule->__args.end(), std::inserter(domains, domains.begin()),
+ [](const auto& argument) {
+ char* domain;
+ switch (argument.second)
+ { case DomainAnnotation::FUNCTION:
+ domain = "function";
+ break;
+ case DomainAnnotation::VARIABLE:
+ domain = "variable";
+ break;
+ }
+
+ return QString("%1(%2)").arg(domain).arg(argument.first.c_str());
+ });
+
+ std::QStringList vars;
+ std::transform(rule->__args.begin(), rule->__args.end(), std::inserter(vars, vars.begin()),
+ [](const auto& argument) {
+ return argument.first.c_str();
+ });
+
+ std::QStringList guards;
+ std::transform(rule->__guards.begin(), rule->__guards.end(), std::inserter(guards, guards.begin()),
+ [](const MetaExpression& guard) {
+ return compile(guard)._c_str();
+ });
+
+ QStringList&& branches = compileNeg(rule->__condition);
+
+ for(const std::string& branch: branches)
+ {
+ std::string listener = registerListener(rule->__message);
+
+ result = QString("%1(%2):-%3, %4, %5")
+ .arg(listener.c_str())
+ .arg(vars.join(", "))
+ .arg(branch.c_str())
+ .arg(guards.join(", "))
+ .arg(domains.join(", "));
+
+ __partGeneral<< result << endl;
+ }
+}
+
+QStringList
+ClaspLayer::compile(const Expression& e) const
+{
+ QStringList result;
+
+ switch(e.__op)
+ {
+ case Operator::CALL:
+ assert(e.__state == COMPOUND);
+
+ std::list<QStringList> operands;
+ std::transform(e.operands.begin(), e.operands.end(), std::inserter(operands, operands().begin()),
+ [](const Expression& e) {return compile(e);});
+
+ QStringList&& operands_ = multiplyLists(operands);
+ result.append(QString("%1(%2)").arg(e.__valueS.c_str()).arg(operands_.join(", ")));
+ break;
+
+ case Operator::NONE:
+ switch (e.__state)
+ {
+ case Expression::IDENT:
+ result.append(e.__valueS);
+ break;
+
+ case Expression::NUMBER:
+ result.append(e.__valueD);
+ break;
+
+ default:
+ assert(true);
+ }
+ break;
+ }
+
+ return result;
+}
+
+QStringList compileNeg(const Expression& e) const
+{
+ QStringList result;
+ switch(__op)
+ {
+ case Operator::IMPL:
+ assert(e.__state == COMPOUND);
+ assert(e.operands.size() == 2);
+ QStringList operands1 = compile(e.operands.at(0));
+ QStringList operands2 = compile(e.operands.at(1));
+
+ for (const auto& op1: operands1)
+ for (const auto& op2: operands2)
+ {
+ result.append(QString("%1, not %2").arg(op1).arg(op2));
+ }
+ break;
+
+ default:
+ assert(true);
+ }
+
+ return result;
+}
+
+void
+ClaspLayer::run()
+{
+ ostringstream program;
+ program << __partTags.str() << __partGeneral.str();
+ cout << program.str() << endl;
+
+ const char* argv[] = {nullptr, nullptr};
+ ClingoLib ctl(2, argv);
+
+ //prg.add("p", ["t"], "q(t).")
+ Gringo::FWStringVec vars{};
+ ctl.add("base", vars, program.str());
+
+ //prg.ground([("p", [2])])
+ Gringo::Control::GroundVec vals{std::make_pair("base", Gringo::FWValVec {})};
+ ctl.ground(vals, Gringo::Any());
+
+ //solve
+ Gringo::Control::Assumptions as;
+ Gringo::SolveResult result = ctl.solve(Gringo::Control::ModelHandler([&](Gringo::Model const &model){return this->onModel(model);}), std::move(as));
+
+ if (result == Gringo::SolveResult::SAT)
+ {
+ cout << "SUCCESSFULLY" << endl;
+ } else {
+ cout << "UNSUCCESSFULLY" << endl;
+ }
+}
+
+ClaspLayer::ClaspLayer()
+{}
+
+/*
+void AspOutPrinter::reportSolution(const Clasp::Solver&, const Clasp::Enumerator&, bool complete) {
+ if (complete) std::cout << "No more models!" << std::endl;
+ else std::cout << "More models possible!" << std::endl;
+}
+
+
+void AspOutPrinter::reportModel(const Clasp::Solver& s, const Clasp::Enumerator&) {
+ std::cout << "Model " << s.stats.solve.models << ": \n";
+// get the symbol table from the solver
+ const Clasp::AtomIndex& symTab = *s.strategies().symTab;
+ for (Clasp::AtomIndex::const_iterator it = symTab.begin(); it != symTab.end(); ++it)
+ {
+// print each named atom that is true w.r.t the current assignment
+ }
+ std::cout << std::endl;
+}
+
+*/
+
+
+/*****************************************
+ * CFGraph
+ *****************************************
+ */
+
+void
+CFGraph::addNode(FID function, std::string&& tag)
+{
+ __nodes.insert(make_pair(function, move(tag)));
+}
+
+bool
+CFGraph::existsNode(FID function) const
+{
+ return __nodes.count(function);
+}
+
+void
+CFGraph::addLink(FID nodeFrom, FID nodeTo)
+{
+ assert(__nodes.count(nodeFrom));
+ assert(__nodes.count(nodeTo));
+
+ __relations.insert(std::make_pair(nodeFrom, nodeTo));
+}
diff --git a/cpp/src/clasplayer.h b/cpp/src/clasplayer.h
new file mode 100644
index 0000000..7a8495e
--- /dev/null
+++ b/cpp/src/clasplayer.h
@@ -0,0 +1,44 @@
+#ifndef CLASPLAYER_H
+#define CLASPLAYER_H
+#include <string>
+#include <gringo/control.hh>
+#include <ast.h>
+
+typedef std::pair<std::string, AnnotationModifier> Tag;
+
+class CFGraph;
+
+class ClaspLayer
+{
+
+public:
+ ClaspLayer();
+
+ void addFunctionTags(const std::string& function, const std::vector<Tag>& tags);
+ void addCFGData(CFGraph&& graph);
+ void addWarningRule(const char* rule);
+
+ void run();
+
+private:
+ std::ostringstream __partTags;
+ std::ostringstream __partGeneral;
+
+ bool onModel(Gringo::Model const & model);
+};
+
+class CFGraph
+{
+ friend class ClaspLayer;
+public:
+ void addNode(FID function, std::string&& tag);
+ void addLink(FID nodeFrom, FID nodeTo);
+ bool existsNode(FID function) const;
+ void print(std::ostream& cout) const;
+
+private:
+ std::map<FID, FID> __relations;
+ std::map<FID, std::string> __nodes;
+};
+
+#endif
diff --git a/cpp/src/llvmlayer.cpp b/cpp/src/llvmlayer.cpp
index 97f5978..99a16b7 100644
--- a/cpp/src/llvmlayer.cpp
+++ b/cpp/src/llvmlayer.cpp
@@ -1,13 +1,17 @@
#include "llvmlayer.h"
using namespace llvm;
LLVMLayer::LLVMLayer()
:builder(getGlobalContext())
{
}
void
LLVMLayer::moveToGarbage(void *o)
{
__garbage.push_back(o);
}
+
+LLVMExpression::LLVMExpression(Expression &&e)
+ : Delegate<Expression>(e)
+{}
diff --git a/cpp/src/llvmlayer.h b/cpp/src/llvmlayer.h
index 6dec359..7cbe58e 100644
--- a/cpp/src/llvmlayer.h
+++ b/cpp/src/llvmlayer.h
@@ -1,28 +1,31 @@
#ifndef LLVMLAYER_H
#define LLVMLAYER_H
#include "llvm/IR/Module.h"
#include "llvm/IR/Function.h"
#include "llvm/PassManager.h"
#include "llvm/IR/CallingConv.h"
-#include "llvm/Analysis/Verifier.h"
-#include "llvm/Assembly/PrintModulePass.h"
+#include "llvm/IR/Verifier.h"
+#include "llvm/IR/IRPrintingPasses.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/LLVMContext.h"
+//#include "ast.h"
+
class LLVMLayer
{
public:
LLVMLayer();
llvm::Module* module;
llvm::IRBuilder<> builder;
void moveToGarbage(void* o);
+ llvm::Value* compile() const;
private:
std::vector<void*> __garbage;
};
#endif // LLVMLAYER_H
diff --git a/cpp/src/main.cpp b/cpp/src/main.cpp
index 3c81c44..e68bba5 100644
--- a/cpp/src/main.cpp
+++ b/cpp/src/main.cpp
@@ -1,59 +1,59 @@
#include <iostream>
-#include "llvm/Module.h"
+#include "llvm/IR/Module.h"
#include "llvm/Function.h"
#include "llvm/PassManager.h"
#include "llvm/CallingConv.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/Support/IRBuilder.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
int main()
{
LLVMContext& ctx = makeLLVMModule();
Module* m = new Module("test");
Constant* c = m->getOrInsertFunction("mul_add",
/*ret type*/ IntegerType::get(ctx,32),
/*args*/ IntegerType::get(ctx,32),
IntegerType::get(ctx, 32),
IntegerType::get(ctx,32),
/*varargs terminated with null*/ NULL);
Function* mul_add = cast<Function>(c);
mul_add->setCallingConv(CallingConv::C);
Function::arg_iterator args = mul_add->arg_begin();
Value* x = args++;
x->setName("x");
Value* y = args++;
y->setName("y");
Value* z = args++;
z->setName("z");
BasicBlock* block = BasicBlock::Create(getGlobalContext(), "entry", mul_add);
IRBuilder<> builder(block);
Value* tmp = builder.CreateBinOp(Instruction::Mul,
x, y, "tmp");
Value* tmp2 = builder.CreateBinOp(Instruction::Add,
tmp, z, "tmp2");
builder.CreateRet(tmp2);
verifyModule(*m, PrintMessageAction);
PassManager man;
man.add(createPrintModulePass(&outs()));
man.run(*m);
delete m;
return 0;
}
diff --git a/cpp/src/pass/cfgpass.cpp b/cpp/src/pass/cfgpass.cpp
new file mode 100644
index 0000000..844abc3
--- /dev/null
+++ b/cpp/src/pass/cfgpass.cpp
@@ -0,0 +1,75 @@
+#include "cfgpass.h"
+#include <QString>
+
+using namespace std;
+
+CFGPass::CFGPass(const AST& entity)
+ : __root(entity)
+{
+
+}
+
+void
+CFGPass::process(const Expression& entity, const FID funcId)
+{
+ switch(entity.__state)
+ {
+ case Expression::COMPOUND:
+ for (const Expression& op: entity.operands)
+ {
+ process(op, funcId);
+ }
+
+ if (entity.__op == Operator::CALL)
+ {
+ const std::string& calleeName = entity.__valueS;
+ assert(__root.__indexFunctions.count(calleeName));
+ FID calleeId = __root.__indexFunctions.at(calleeName);
+
+ if (!__graph.existsNode(calleeId))
+ {
+ __graph.addNode(calleeId, string(calleeName));
+ process(calleeId);
+ }
+
+ __graph.addLink(funcId, calleeId);
+ }
+ break;
+
+ case Expression::IDENT:
+ const Function& func = __root.getFunctionById(funcId);
+ const std::string& identName = entity.__valueS;
+
+ assert(func.__vartable.count(identName));
+ VID identId = func.__vartable.at(identName);
+
+ if (func.__declarations.count(identId))
+ {
+ const Expression& identExpr = func.__declarations.at(identId);
+ process(identExpr, funcId);
+ }
+ }
+}
+
+void
+CFGPass::process(const FID funcId)
+{
+ const Function& f = __root.getFunctionById(funcId);
+ process(f.__body, funcId);
+}
+
+void
+CFGPass::run(ClaspLayer& clasp)
+{
+ __graph = CFGraph();
+ cout << "CFGPass::run" << endl;
+
+ for(FID f=0, fcount=__root.getFunctionsCount(); f<fcount; ++f)
+ {
+ const Function& func = __root.getFunctionById(f);
+ __graph.addNode(f, string(func.getName()));
+ process(f);
+ }
+
+ clasp.addCFGData(std::move(__graph));
+}
diff --git a/cpp/src/pass/cfgpass.h b/cpp/src/pass/cfgpass.h
new file mode 100644
index 0000000..aff1589
--- /dev/null
+++ b/cpp/src/pass/cfgpass.h
@@ -0,0 +1,25 @@
+// Control Flow Graph determination pass
+
+#ifndef CFGPASS_H
+#define CFGPASS_H
+
+#include "ast.h"
+#include <set>
+#include <iostream>
+#include "clasplayer.h"
+
+class CFGPass
+{
+public:
+ CFGPass(const AST& entity);
+ void run(ClaspLayer& clasp);
+
+private:
+ const AST& __root;
+ CFGraph __graph;
+
+ void process(const Expression& entity, const FID funcId);
+ void process(const FID funcId);
+};
+
+#endif // CFGPASS_H
diff --git a/cpp/src/pass/functiontagspass.cpp b/cpp/src/pass/functiontagspass.cpp
new file mode 100644
index 0000000..e57c472
--- /dev/null
+++ b/cpp/src/pass/functiontagspass.cpp
@@ -0,0 +1,18 @@
+#include "functiontagspass.h"
+#include <QString>
+using namespace std;
+
+FunctionTagsPass::FunctionTagsPass(AST& root)
+ : __root(root)
+{
+}
+
+void
+FunctionTagsPass::run(ClaspLayer& clasp)
+{
+ for (FID id=0, count = __root.getFunctionsCount(); id < count; ++id)
+ {
+ const Function& f = __root.getFunctionById(id);
+ clasp.addFunctionTags(f.getName(), f.getAnnotations());
+ }
+}
diff --git a/cpp/src/pass/functiontagspass.h b/cpp/src/pass/functiontagspass.h
new file mode 100644
index 0000000..e58020f
--- /dev/null
+++ b/cpp/src/pass/functiontagspass.h
@@ -0,0 +1,17 @@
+#ifndef FUNCTIONTAGSPASS_H
+#define FUNCTIONTAGSPASS_H
+
+#include "ast.h"
+#include <iostream>
+#include "clasplayer.h"
+
+class FunctionTagsPass
+{
+public:
+ FunctionTagsPass(AST& root);
+ void run(ClaspLayer& clasp);
+private:
+ const AST& __root;
+};
+
+#endif // FUNCTIONTAGSPASS_H
diff --git a/cpp/src/tests.cpp b/cpp/src/tests.cpp
deleted file mode 100644
index 3520067..0000000
--- a/cpp/src/tests.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-#include "Scanner.h"
-#include "Parser.h"
-#include "ast.h"
-#include <memory>
-
-using namespace std;
-
-void testParser_1()
-{
- shared_ptr<Scanner> scanner(new Scanner(L"scripts/input.xreate"));
- shared_ptr<Parser> parser(new Parser(scanner.get()));
-
- AST& root = parser->root;
- LLVMLayer l;
-
- root.compile(l);
- root.run(l);
-}
-
-int main()
-{
- return 0;
-}
diff --git a/cpp/tests/tests.cpp b/cpp/tests/tests.cpp
new file mode 100644
index 0000000..726d165
--- /dev/null
+++ b/cpp/tests/tests.cpp
@@ -0,0 +1,61 @@
+#include "Scanner.h"
+#include "Parser.h"
+#include "ast.h"
+#include <memory>
+#include <iostream>
+#include "cfgpass.h"
+#include "clasplayer.h"
+#include "functiontagspass.h"
+#include <sstream>
+
+using namespace std;
+
+void testParser_1()
+{
+ shared_ptr<Scanner> scanner(new Scanner(L"scripts/input.xreate"));
+ shared_ptr<Parser> parser(new Parser(scanner.get()));
+ parser->Parse();
+ flush(cout);
+
+ AST& root = parser->root;
+ LLVMLayer l;
+
+ root.compile(l);
+ root.run(l);
+}
+
+void testClasp2()
+{
+ shared_ptr<Scanner> scanner(new Scanner(L"scripts/input.xreate"));
+ shared_ptr<Parser> parser(new Parser(scanner.get()));
+ parser->Parse();
+ flush(cout);
+
+ if (parser->errors->count)
+ {
+ cout << "Found " << parser->errors->count << " errors. Stop" << endl;
+ exit(1);
+ }
+
+ AST& root = parser->root;
+ ClaspLayer clasp;
+
+ FunctionTagsPass(root).run(clasp);
+
+ CFGPass(root).run(clasp);
+ clasp.addRule(":- call(X, Y), tag(Y, unsafe), not tag(X, unsafe), function(X), function(Y).");
+
+ clasp.run();
+}
+
+void tests_ListsMultiply()
+{
+
+}
+
+int main()
+{
+ testClasp2();
+
+ return 0;
+}
diff --git a/cpp/xreate/xreate.pro b/cpp/xreate/xreate.pro
deleted file mode 100644
index 443eddf..0000000
--- a/cpp/xreate/xreate.pro
+++ /dev/null
@@ -1,29 +0,0 @@
-TEMPLATE = app
-CONFIG += console
-CONFIG -= qt
-
-#INCLUDEPATH += /usr/lib/llvm-3.4/include
-LIBS += -L/usr/lib/llvm-3.4/lib `llvm-config-3.4 --libs` -lpthread -lffi -ltinfo -ldl -lm
-QMAKE_CXXFLAGS += -I/usr/lib/llvm-3.4/include `llvm-config-3.4 --cxxflags` -std=c++0x
-
-
-SOURCES += \
- # ../src/main.cpp \
- ../../coco/Parser.cpp \
- ../../coco/Scanner.cpp \
- ../src/ast.cpp \
- ../src/tests.cpp \
- ../src/llvmlayer.cpp
-
-HEADERS += \
- ../../coco/Parser.h \
- ../../coco/Scanner.h \
- ../src/ast.h \
- ../src/llvmlayer.h
-
-INCLUDEPATH += \
- ../src \
- ../../coco
-
-
-
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..463d822
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,62 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.xreate</groupId>
+ <artifactId>xreate</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>jar</packaging>
+
+ <name>xreate</name>
+ <url>http://maven.apache.org</url>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.3.2</version>
+ <configuration>
+ <source>1.6</source>
+ <target>1.6</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.10</version>
+ <type>jar</type>
+ </dependency>
+ <dependency>
+ <groupId>org.antlr</groupId>
+ <artifactId>antlr</artifactId>
+ <version>3.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.antlr</groupId>
+ <artifactId>antlr-runtime</artifactId>
+ <version>3.2</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>11.0.2</version>
+ </dependency>
+ <dependency>
+ <groupId>javolution</groupId>
+ <artifactId>javolution</artifactId>
+ <version>5.5.1</version>
+ </dependency>
+ <dependency>
+ <groupId>jllvm</groupId>
+ <artifactId>jllvm</artifactId>
+ <version>2.8</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/problems/example-computations.lp b/problems/example-computations.lp
index 762f2db..4cdd8a3 100644
--- a/problems/example-computations.lp
+++ b/problems/example-computations.lp
@@ -1,49 +1,49 @@
%defines:
implementation(hashlist). implementation(linkedlist). implementation(treelist). implementation(computation).
operation(at). operation(sort). operation(insert). operation(seqaccess).
connection_type(ct_inherits). connection_type(ct_convert).
relation (recommends). relation (satisfied). relation(unsupported).
relation_score(satisfied, 0).
relation_score(recommends, 1).
relation_score(unsupported, -1).
%integration facts:
relation_op(seqaccess, computation, recommends).
relation_op(at, hashlist, recommends). relation_op(at,treelist, satisfied).
relation_op(sort, linkedlist, satisfied). relation_op(sort, treelist, satisfied). relation_op(sort, hashlist, unsupported).
%static analysis:
var(a).var(tmp2). var(b). var(tmp3).
var_connection(a, tmp2).
bind_var_op(tmp2, seqaccess).
var_connection(tmp2, b, ct_inherits).
var_connection(b, tmp3).
bind_var_op(tmp3, seqaccess).
%domain rules:
impl_fulfill(OP, IMPL, SCORE):- relation_op(OP, IMPL, RL), relation_score(RL, SCORE), operation(OP), implementation(IMPL), RL!=unsupported.
impl_not_fulfill(OP, IMPL):- relation_op(OP, IMPL, unsupported).
%reasoning rules:
{ var_connection(VAR_FROM, VAR_TO, CT):connection_type(CT) }1 :- var_connection(VAR_FROM, VAR_TO).
var_cluster_root(VAR) :- {var_connection(VAR_F, VAR, ct_inherits): var(VAR_F)} 0, var(VAR).
var_cluster(VAR0, VAR_TO) :- var_connection(VAR0, VAR_TO, ct_inherits), var_cluster_root(VAR0).
var_cluster(VAR0, VAR_TO2) :- var_connection(VAR_TO1, VAR_TO2, ct_inherits), var_cluster(VAR0, VAR_TO1).
var_cluster(VAR0, VAR0):- var_cluster_root(VAR0).
impl_fulfill_cluster(VAR0, OP, IMPL, SCORE) :- var_cluster(VAR0, VAR_ANY), bind_var_op(VAR_ANY, OP), impl_fulfill(OP, IMPL, SCORE), var_cluster_root(VAR0).
impl_not_fulfill_cluster(VAR0, IMPL):-var_cluster(VAR0, VAR_ANY), bind_var_op(VAR_ANY, OP), impl_not_fulfill(OP, IMPL), var_cluster_root(VAR0).
bind_var_impl(VAR0, IMPL, SCORE_RESULT) :- SCORE_RESULT = #sum[impl_fulfill_cluster(VAR0, _, IMPL, SCORE) = SCORE], {impl_not_fulfill_cluster(VAR0, IMPL)}0, var_cluster_root(VAR0), implementation(IMPL).
%pretty output:
#hide.
#show chosen_impl/2.
- %#show bind_var_impl/3.
- %#show var_cluster_owner/1.
- %#show var_connection/3.
- %#show bind_var_op/2.
+ #show bind_var_impl/3.
+ #show var_cluster_owner/1.
+ #show var_connection/3.
+ #show bind_var_op/2.
diff --git a/problems/test.lp b/problems/test.lp
new file mode 100644
index 0000000..8c8a729
--- /dev/null
+++ b/problems/test.lp
@@ -0,0 +1,12 @@
+% p(1..3). q(2..4).
+% { r(X): p(X), r(X): q(X) }.
+% s :- #sum { r(X)=X: p(X): q(X) } 1.
+
+%p(1..50).
+%count(X, Y):- Y = #sum {Z, Z: p(Z), Z >= X}, p(X).
+
+p(1..3).
+2 {q(X) : p(X)}.
+q(2).
+:- not q(3).
+:~ p(X), not q(X).[X]
\ No newline at end of file
diff --git a/problems/unsafe-code.lp b/problems/unsafe-code.lp
new file mode 100644
index 0000000..82d0b44
--- /dev/null
+++ b/problems/unsafe-code.lp
@@ -0,0 +1,10 @@
+%Static analysis: CFG
+function(testfunc3) .
+function(testfunc2) .
+call(testfunc2, testfunc3) .
+
+%Function tags:
+tag(testfunc3, unsafe).
+%tag(testfunc2, unsafe).
+
+:- call(X, Y), tag(Y, unsafe), not tag(X, unsafe), function(X), function(Y).
\ No newline at end of file
diff --git a/project/diploma-doc.doc b/project/diploma-doc.doc
deleted file mode 100644
index 00d6285..0000000
Binary files a/project/diploma-doc.doc and /dev/null differ
diff --git a/project/diploma.doc b/project/diploma.doc
index e10e822..869f589 100644
Binary files a/project/diploma.doc and b/project/diploma.doc differ
diff --git a/project/diploma.odt b/project/diploma.odt
deleted file mode 100644
index e20fd80..0000000
Binary files a/project/diploma.odt and /dev/null differ
diff --git a/project/draft.odt b/project/draft.odt
index 26cd7ca..422f2ae 100644
Binary files a/project/draft.odt and b/project/draft.odt differ
diff --git a/scripts/input.xreate b/scripts/input.xreate
index 679b16f..22294b3 100644
--- a/scripts/input.xreate
+++ b/scripts/input.xreate
@@ -1,16 +1,45 @@
+
+/*
+//unsafe code propagation rule
+rule: (X: function, Y: function)
+case X calls Y
+ {
+ warning Y has unsafe --> X has unsafe
+ message format("function A should not call unsafe code B", X as A, Y as B)
+ }
+
+*/
+
+testfunc3 = function: (a: num, b: num)->num , unsafe //function tags list
+{
+ x = a+b: num;
+ y = a - b: num;
+
+ (x + y) / 2;
+}
+
+testfunc2 = function: (a: num)->bool // because of testfunc3 marked as unsafe code,
+ // testfunc2 should be marked so too
+{
+ b = testfunc3(a+1, a-1): num;
+ (b==0);
+}
+
+/*
find6 = function: bool
{
x = [1, 2, 3, 4, 5, 6, 7]: [num]; //эффективная инициализация
y = map (x) [el]-> {2 * el};
exists(y, 12);
}
exists = function: (list:[a], el: a)->bool
{
acc: bool;
acc = reduce(list, false) [el, acc] ->
{
acc = acc & (el == e): saturated(true);
}
}
+*/
diff --git a/src/main/java/org/xreate/ASTNode.java b/src/main/java/org/xreate/ASTNode.java
new file mode 100644
index 0000000..02b1e07
--- /dev/null
+++ b/src/main/java/org/xreate/ASTNode.java
@@ -0,0 +1,89 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.xreate;
+
+import com.google.common.collect.ListMultimap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+
+public class ASTNode{
+ public ASTNode acceptComputableVisitor(ComputableAnalysis visitor) throws NoSuchMethodException, IllegalAccessException, Throwable{
+ Method compute = visitor.getClass().getDeclaredMethod("ifComputable", this.getClass());
+
+ ASTNode v = (ASTNode) compute.invoke(visitor, this);
+
+ return new ASTValue(0);
+ }
+}
+
+class ASTAssignment extends ASTNode{
+ public ASTVar var;
+ public ASTExpression value;
+}
+
+class ASTExpression extends ASTNode{
+ ListMultimap <ASTFunction, ASTExpression> representation;
+
+ public List<ASTVar> getUsedVars(){
+ return Lists.newArrayList(); //stub
+ }
+
+
+ public ASTNode eval(Map<ASTVar, ASTNode> substitutions)
+ {return new ASTValue(0);} //stub
+
+}
+
+class ASTFunction extends ASTNode{
+ String representation;
+ int fpcount; //formal parameters count
+}
+
+
+class ASTValue extends ASTExpression{
+ public int representation;
+
+ public ASTValue(int source){
+ representation = source;
+ }
+}
+
+class ASTVar extends ASTExpression{
+ int id;
+
+ public static Map<ASTVar, ASTValue> substitute(List<ASTVar> vars)
+ {return Maps.newHashMap();}
+
+ public ASTVar(){
+ id =0;
+ }
+}
+
+
+
+
+/*
+ * fargs - formal args
+ *
+ *
+ *
+ */
+
+/*
+ *
+ *
+ * block (fargs, body-list)
+ * expression -: atom
+ * atom :- val, var
+ * assignment
+ * sequence
+ *
+ */
+
diff --git a/src/main/java/org/xreate/App.java b/src/main/java/org/xreate/App.java
new file mode 100644
index 0000000..ba10572
--- /dev/null
+++ b/src/main/java/org/xreate/App.java
@@ -0,0 +1,10 @@
+package org.xreate;
+
+public class App
+{
+ public static void main( String[] args ) throws NoSuchMethodException, IllegalAccessException, Throwable {
+ TestRunner2 runner = new TestRunner2();
+
+ runner.constructAndRun();
+ }
+}
diff --git a/src/main/java/org/xreate/ComputableAnalisys.java b/src/main/java/org/xreate/ComputableAnalisys.java
new file mode 100644
index 0000000..d64a7cc
--- /dev/null
+++ b/src/main/java/org/xreate/ComputableAnalisys.java
@@ -0,0 +1,66 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.xreate;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ *
+ * @author pgess
+ */
+class ComputableAnalysis{
+ protected Map<ASTVar, ASTNode> computedStore;
+
+ public ASTNode ifComputable (ASTNode node){
+ return node;
+ }
+
+ /*
+ * null - если не переменная не вычислима
+ */
+ public ASTNode ifComputable (ASTVar node){
+
+ return computedStore.get(node);
+
+ /*
+ Optional<ASTValue> value = Optional.of ();
+ return false;
+ */
+ }
+
+ /*
+ * null - если выражение не вычислимо
+ */
+ /*
+ public ASTNode ifComputable (ASTExpression node){
+ List<ASTVar> vars = node.getUsedVars();
+
+ Map<ASTVar, ASTValue> subs = ASTVar.substitute(vars);
+
+ if (computedStore.keySet().containsAll(vars)){
+
+ //computedStore.
+ ASTNode result = node.eval(subs);
+ return result;
+ }
+
+
+ return null;
+ }
+
+ */
+
+ public ASTNode ifComputable (ASTAssignment node) throws NoSuchMethodException, IllegalAccessException, Throwable{
+
+ ASTNode value = node.value.acceptComputableVisitor(this);
+
+ if (value != null){
+ computedStore.put(node.var, value);
+ }
+
+ return value;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/xreate/SemanticAnalysis.java b/src/main/java/org/xreate/SemanticAnalysis.java
new file mode 100644
index 0000000..a411db6
--- /dev/null
+++ b/src/main/java/org/xreate/SemanticAnalysis.java
@@ -0,0 +1,15 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.xreate;
+
+import java.util.Map;
+
+/**
+ *
+ * @author pgess
+ */
+public class SemanticAnalysis {
+ public Map<String, String> opcodes;
+}
diff --git a/src/main/java/org/xreate/TestRunner2.java b/src/main/java/org/xreate/TestRunner2.java
new file mode 100644
index 0000000..5c519c4
--- /dev/null
+++ b/src/main/java/org/xreate/TestRunner2.java
@@ -0,0 +1,114 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.xreate;
+
+import com.google.common.collect.Maps;
+import java.math.BigInteger;
+import org.jllvm.*;
+import org.jllvm.bindings.*;
+import org.junit.Test;
+/**
+ *
+ * @author pgess
+ */
+public class TestRunner2 {
+
+ protected LLVMModule module;
+
+ public void setModule(LLVMModule module){
+ this.module = module;
+ }
+
+ public void constructAndRun() throws Exception{
+ boolean isNative = LLVMTargetData.initializeNativeTarget();
+ module = new LLVMModule("xreate_first_test");
+
+ LLVMValue func = constructBody();
+ runBody(func);
+ }
+
+ public LLVMValue constructBody() throws Exception{
+ LLVMConstantInteger a = LLVMConstantInteger.constantInteger(LLVMIntegerType.i32, 10, true);
+ LLVMConstantInteger b = LLVMConstantInteger.constantInteger(LLVMIntegerType.i32, 20, true);
+ LLVMConstantInteger c = LLVMConstantInteger.constantInteger(LLVMIntegerType.i32, 3, true);
+ LLVMInstructionBuilder builder = new LLVMInstructionBuilder();
+
+ LLVMInstruction i = new LLVMAddInstruction(builder, a, b, false, "a+b");
+ i = new LLVMMultiplyInstruction(builder, c, i, false, "c * (a + b)");
+
+ //LLVMModule module; // module =
+ LLVMFunctionType func_test1_type;
+
+
+
+ LLVMType[] types = new LLVMType[0];
+ //types[0] = new LLVMVoidType();
+
+ func_test1_type = new LLVMFunctionType(LLVMIntegerType.i32, types, false);
+
+ LLVMFunction test1 = new LLVMFunction(module, "test1", func_test1_type);
+ LLVMBasicBlock entry = test1.appendBasicBlock("entry");
+ builder.positionBuilderAtEnd(entry);
+
+ new LLVMReturnInstruction(builder, i);
+
+ SWIGTYPE_p_p_char outerrs = ExecutionEngine.new_StringArray(1);
+ int x = Analysis.LLVMVerifyFunction(test1.getInstance(), LLVMVerifierFailureAction.LLVMReturnStatusAction);
+ x = Analysis.LLVMVerifyModule(module.getInstance(), LLVMVerifierFailureAction.LLVMReturnStatusAction, outerrs);
+
+ ExecutionEngine.delete_StringArray(outerrs); outerrs = null;
+
+ return test1;
+ }
+
+ public void runBody(LLVMValue test1 ){
+
+
+ SWIGTYPE_p_p_LLVMOpaqueExecutionEngine engines = ExecutionEngine.new_LLVMExecutionEngineRefArray(1);
+ SWIGTYPE_p_p_char outerrs = ExecutionEngine.new_StringArray(1);
+ int success = ExecutionEngine.LLVMCreateJITCompilerForModule(engines,module.getInstance(), 0, outerrs);
+ String outerr = ExecutionEngine.StringArray_getitem(outerrs,0);
+ ExecutionEngine.delete_StringArray(outerrs); outerrs = null;
+ SWIGTYPE_p_LLVMOpaqueExecutionEngine instance_ = ExecutionEngine.LLVMExecutionEngineRefArray_getitem(engines,0);
+ ExecutionEngine.delete_LLVMExecutionEngineRefArray(engines); engines = null;
+
+ /*
+ LLVMJitCompiler engine = new LLVMJitCompiler(module);
+
+ LLVMGenericValue res = engine.runFunction(test1, args);
+
+ //
+ BigInteger result = ExecutionEngine.LLVMGenericValueToInt(res.getInstance(), 0);
+ */
+
+ LLVMGenericValue[] args = new LLVMGenericValue[0];
+
+
+ SWIGTYPE_p_p_LLVMOpaqueGenericValue arg_array = ExecutionEngine.new_LLVMGenericValueRefArray(args.length);
+ for(int ii=0;ii<args.length;ii++)
+ ExecutionEngine.LLVMGenericValueRefArray_setitem(arg_array,ii,args[ii].getInstance());
+
+ SWIGTYPE_p_LLVMOpaqueGenericValue res = ExecutionEngine.LLVMRunFunction(instance_,test1.getInstance(),args.length,arg_array);
+ ExecutionEngine.delete_LLVMGenericValueRefArray(arg_array);
+
+ BigInteger result = ExecutionEngine.LLVMGenericValueToInt(res, 0);
+ //LLVMGenericInt result = (LLVMGenericInt) new LLVMGenericValue(res);
+
+
+ /*
+ LLVMJitCompiler program = new LLVMJitCompiler (module);
+ LLVMGenericInt result = (LLVMGenericInt) program.runFunction(test1, new LLVMGenericValue[0]);
+ */
+
+
+ int r = result.intValue();
+
+ System.out.println(r);
+ }
+
+ static {
+ System.loadLibrary("jllvm");
+ }
+}
diff --git a/src/main/java/org/xreate/grammatic/lisp/ASTLispNode.java b/src/main/java/org/xreate/grammatic/lisp/ASTLispNode.java
new file mode 100644
index 0000000..561443f
--- /dev/null
+++ b/src/main/java/org/xreate/grammatic/lisp/ASTLispNode.java
@@ -0,0 +1,73 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.xreate.grammatic.lisp;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import java.util.ArrayList;
+import java.util.Map;
+
+
+public class ASTLispNode {
+ public String caption;
+ public ArrayList<ASTLispNode> parameters = Lists.newArrayList();
+
+ protected Map<String, ASTLispNode> index;
+
+ public ASTLispNode(String c){
+ caption = c;
+ }
+
+ public ASTLispNode add(ASTLispNode node){
+ parameters.add(node);
+ return node;
+ }
+
+ public ASTLispNode get(String node){
+ if (null == index){
+ buildIndex();
+ }
+
+ return index.get(node);
+ }
+
+ protected void buildIndex(){
+ index = Maps.newHashMap();
+
+ for (ASTLispNode param : parameters){
+ index.put(param.caption, param);
+ }
+ }
+}
+class ASTLispConstantNode extends ASTLispNode{
+ public int value;
+
+ public ASTLispConstantNode(String c) {
+ super(c);
+
+ value = Integer.parseInt(c);
+ }
+}
+
+
+class NodeFunctionVarsList {
+ ASTLispNode node;
+
+ NodeFunctionVarsList(ASTLispNode node){
+ this.node = node;
+ }
+
+ String[] getVarNames(){
+ int size = node.parameters.size();
+
+ String[] result = new String[size];
+
+ for(int i=0; i<size; i++){
+ result[i] = node.parameters.get(i).get("name").parameters.get(0).caption;
+ }
+
+ return result;
+ }
+}
diff --git a/src/main/java/org/xreate/grammatic/lisp/LispInterpreter.java b/src/main/java/org/xreate/grammatic/lisp/LispInterpreter.java
new file mode 100644
index 0000000..56a77d3
--- /dev/null
+++ b/src/main/java/org/xreate/grammatic/lisp/LispInterpreter.java
@@ -0,0 +1,260 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.xreate.grammatic.lisp;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import org.antlr.runtime.*;
+import org.jllvm.*;
+import org.jllvm.bindings.*;
+import org.xreate.TestRunner2;
+
+/**
+ *
+ * @author pgess
+ */
+public class LispInterpreter {
+ static Map<String, String> htable;
+ static Map<String, LLVMType> ttable;
+
+ public Map<String, String> opcodes = Maps.newLinkedHashMap();
+ public Map<String, LLVMFunction> functions = Maps.newLinkedHashMap();
+
+
+ protected LLVMInstructionBuilder builder = new LLVMInstructionBuilder();
+ protected LLVMModule module = new LLVMModule("script");
+
+ //"/private/prg/code/xreate/scripts/opcode.li"
+ public void run(String filename) throws IOException, RecognitionException, Exception{
+ ANTLRStringStream in = new ANTLRFileStream(filename);
+
+ Lexer l = new LispLexer(in);
+ CommonTokenStream tokens = new CommonTokenStream(l);
+
+ LispParser p = new LispParser(tokens);
+
+ while (true){
+ ASTLispNode node = p.statement(null);
+
+ handle(node);
+ }
+
+ }
+
+ public void opcodeDef(ASTLispNode node){
+ ArrayList<ASTLispNode> params = node.parameters;
+
+ opcodes.put(params.get(0).caption, params.get(1).caption);
+ }
+
+ public void functionDef(ASTLispNode node) throws Exception{
+ ArrayList<ASTLispNode> nodes_vars = node.get("vars-list").parameters;
+
+ int nsize = nodes_vars.size();
+ LLVMType[] arg_types = new LLVMType[nsize];
+
+ for (int i=0; i<nsize; i++){
+ String type_caption = nodes_vars.get(i).get("type").parameters.get(0).caption;
+ arg_types[i] = ttable.get(type_caption);
+ }
+
+ LLVMType ret_type = ttable.get(node.get("return").get("type").parameters.get(0).caption);
+ String func_name = node.get("name").parameters.get(0).caption;
+
+ LLVMFunctionType func_type =new LLVMFunctionType(ret_type, arg_types, false);
+ LLVMFunction func = new LLVMFunction(module, func_name, func_type);
+
+ LLVMBasicBlock entry = func.appendBasicBlock("entry");
+ builder.positionBuilderAtEnd(entry);
+
+ LLVMValue[] values = func.getParameters();
+ String[] vars = new NodeFunctionVarsList(node.get("vars-list")).getVarNames();
+
+ LLVMValue func_body = new Evaluator(vars, values).eval(node.get("body").parameters.get(0));
+
+ new LLVMReturnInstruction(builder, func_body);
+
+ SWIGTYPE_p_p_char outerrs = ExecutionEngine.new_StringArray(1);
+ int x = Analysis.LLVMVerifyFunction(func.getInstance(), LLVMVerifierFailureAction.LLVMReturnStatusAction);
+ x = Analysis.LLVMVerifyModule(module.getInstance(), LLVMVerifierFailureAction.LLVMReturnStatusAction, outerrs);
+ ExecutionEngine.delete_StringArray(outerrs); outerrs = null;
+
+ functions.put(func_name, func);
+ }
+
+ public int main(ASTLispNode node) throws Exception{
+
+ String func_main_name = node.parameters.get(0).caption;
+ LLVMFunction func_main = functions.get(func_main_name);
+ if (null == func_main){
+ throw new Exception("Main function not found!");
+ }
+
+ boolean isNative = LLVMTargetData.initializeNativeTarget();
+ LispJITRunnerWrapper program = new LispJITRunnerWrapper(module);
+ LLVMGenericValue resultRef = program.runFunction(func_main, new LLVMGenericValue[0]);
+ BigInteger resultBig = ExecutionEngine.LLVMGenericValueToInt(resultRef.getInstance(), 0);
+ int result = resultBig.intValue();
+ return result;
+
+ /*
+ TestRunner2 runner = new TestRunner2();
+ runner.setModule(module);
+ runner.runBody(func_main);
+
+ return 0;
+ *
+ */
+ }
+
+
+
+
+ public Object handle(ASTLispNode node) throws Exception{
+ String caption = node.caption;
+ String method = htable.get(caption);
+
+ if (method == null) {
+ throw new Exception();
+ }
+
+ Method invoker = this.getClass().getDeclaredMethod(method, ASTLispNode.class);
+ return invoker.invoke(this, node);
+ }
+
+ public LispInterpreter(){
+ }
+
+ static {
+ /*
+ * Handler table хранит информацию о соответствии метода и команды
+ */
+ htable = new ImmutableMap.Builder<String, String>()
+ .put("opcode", "opcodeDef")
+ .put("function", "functionDef")
+ .put ("calculate", "calculate")
+ .put("main", "main")
+ .build();
+
+ /*
+ * Types Table - хранит информацию о соответствии типов
+ */
+ ttable = new ImmutableMap.Builder<String, LLVMType>()
+ .put ("i32", LLVMIntegerType.i32)
+ .put ("i16", LLVMIntegerType.i16)
+ .put ("i8", LLVMIntegerType.i8)
+ .build();
+
+
+ }
+
+ class Evaluator{
+ Map<String, LLVMValue> arguments;
+
+ public Evaluator(String[] names, LLVMValue[] values) {
+
+ int size = names.length;
+ arguments = Maps.newHashMapWithExpectedSize(size);
+
+ for(int i=0; i<size; i++){
+ arguments.put(names[i], values[i]);
+ }
+ }
+
+ public LLVMValue LLVMAddInstruction(ASTLispNode node) throws Exception{
+
+ LLVMValue arg1 = eval(node.parameters.get(0));
+ LLVMValue arg2 = eval(node.parameters.get(1));
+
+ return new LLVMAddInstruction(builder, arg1, arg2, false, "add");
+ }
+
+ public LLVMValue LLVMDivideInstruction(ASTLispNode node) throws Exception{
+ LLVMValue arg1 = eval(node.parameters.get(0));
+ LLVMValue arg2 = eval(node.parameters.get(1));
+
+ return new LLVMDivideInstruction(builder, arg1, arg2, LLVMDivideInstruction.DivisionType.UNSIGNEDINT, "div");
+ }
+
+ public LLVMValue LLVMCallFunctionInstruction(ASTLispNode node) throws Exception{
+ LLVMFunction func = functions.get(node.caption);
+
+ int size = node.parameters.size();
+
+ LLVMValue[] args = new LLVMValue[size];
+
+ for (int i=0; i<size; i++){
+ args[i] = eval(node.parameters.get(i));
+ }
+
+// long argsNum = Core.LLVMCountParamTypes(Core.LLVMTypeOf(func.getInstance()));
+
+ SWIGTYPE_p_p_LLVMOpaqueValue args_opaque = Core.new_LLVMValueRefArray(args.length);
+ for(int i=0;i<args.length;i++)
+ Core.LLVMValueRefArray_setitem(args_opaque,i,args[i].getInstance());
+ SWIGTYPE_p_LLVMOpaqueValue instance = Core.LLVMBuildCall(builder.getInstance(),func.getInstance(),args_opaque,args.length, node.caption + "aaa");
+
+ Core.delete_LLVMValueRefArray(args_opaque);
+
+ return new LLVMValue(instance);
+ //return new LLVMCallInstruction(builder, func, args, node.caption);
+ }
+
+ public LLVMValue eval(ASTLispNode node) throws Exception{
+ if (node instanceof ASTLispConstantNode){
+ return LLVMConstantInteger.constantInteger(LLVMIntegerType.i32, ((ASTLispConstantNode) node).value, false);
+ }
+
+ String instruction = opcodes.get(node.caption);
+
+ if (instruction != null) {
+ Method invoker = this.getClass().getDeclaredMethod(instruction, ASTLispNode.class);
+ return (LLVMValue) invoker.invoke(this, node);
+ }
+
+ LLVMValue arg = arguments.get(node.caption);
+
+ if (arg != null){
+ return arg;
+ }
+
+ if (functions.containsKey(node.caption)){
+ return LLVMCallFunctionInstruction(node);
+ }
+
+ throw new Exception("Cant evaluate symbol: " + node.caption);
+ }
+
+ }
+}
+
+
+
+class LispJITRunnerWrapper extends LLVMExecutionEngine{
+ LispJITRunnerWrapper(LLVMModule module) throws Exception{
+ super();
+
+ SWIGTYPE_p_p_LLVMOpaqueExecutionEngine engines = ExecutionEngine.new_LLVMExecutionEngineRefArray(1);
+ SWIGTYPE_p_p_char outerrs = ExecutionEngine.new_StringArray(1);
+ int success = ExecutionEngine.LLVMCreateJITCompilerForModule(engines,module.getInstance(), 0, outerrs);
+ String outerr = ExecutionEngine.StringArray_getitem(outerrs,0);
+ ExecutionEngine.delete_StringArray(outerrs); outerrs = null;
+ instance = ExecutionEngine.LLVMExecutionEngineRefArray_getitem(engines,0);
+ ExecutionEngine.delete_LLVMExecutionEngineRefArray(engines); engines = null;
+
+ /*
+ if(success == 0)
+ throw new Exception(outerr);
+ *
+ */
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/xreate/grammatic/lisp/LispLexer.java b/src/main/java/org/xreate/grammatic/lisp/LispLexer.java
new file mode 100644
index 0000000..8f8d69a
--- /dev/null
+++ b/src/main/java/org/xreate/grammatic/lisp/LispLexer.java
@@ -0,0 +1,368 @@
+package org.xreate.grammatic.lisp;
+
+// $ANTLR 3.4 /private/prg/code/xreate/antlr/lisp.g 2012-04-07 17:57:03
+
+import org.antlr.runtime.*;
+import java.util.Stack;
+import java.util.List;
+import java.util.ArrayList;
+
+@SuppressWarnings({"all", "warnings", "unchecked"})
+public class LispLexer extends Lexer {
+ public static final int EOF=-1;
+ public static final int T__6=6;
+ public static final int T__7=7;
+ public static final int T__8=8;
+ public static final int WHITESPACE=4;
+ public static final int WORD=5;
+
+ // delegates
+ // delegators
+ public Lexer[] getDelegates() {
+ return new Lexer[] {};
+ }
+
+ public LispLexer() {}
+ public LispLexer(CharStream input) {
+ this(input, new RecognizerSharedState());
+ }
+ public LispLexer(CharStream input, RecognizerSharedState state) {
+ super(input,state);
+ }
+ public String getGrammarFileName() { return "/private/prg/code/xreate/antlr/lisp.g"; }
+
+ // $ANTLR start "T__6"
+ public final void mT__6() throws RecognitionException {
+ try {
+ int _type = T__6;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // /private/prg/code/xreate/antlr/lisp.g:2:6: ( '(' )
+ // /private/prg/code/xreate/antlr/lisp.g:2:8: '('
+ {
+ match('(');
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "T__6"
+
+ // $ANTLR start "T__7"
+ public final void mT__7() throws RecognitionException {
+ try {
+ int _type = T__7;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // /private/prg/code/xreate/antlr/lisp.g:3:6: ( ')' )
+ // /private/prg/code/xreate/antlr/lisp.g:3:8: ')'
+ {
+ match(')');
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "T__7"
+
+ // $ANTLR start "T__8"
+ public final void mT__8() throws RecognitionException {
+ try {
+ int _type = T__8;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // /private/prg/code/xreate/antlr/lisp.g:4:6: ( ',' )
+ // /private/prg/code/xreate/antlr/lisp.g:4:8: ','
+ {
+ match(',');
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "T__8"
+
+ // $ANTLR start "WHITESPACE"
+ public final void mWHITESPACE() throws RecognitionException {
+ try {
+ int _type = WHITESPACE;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // /private/prg/code/xreate/antlr/lisp.g:3:12: ( ( '\\t' | ' ' | '\\r' | '\\n' | '\\u000C' )+ )
+ // /private/prg/code/xreate/antlr/lisp.g:3:14: ( '\\t' | ' ' | '\\r' | '\\n' | '\\u000C' )+
+ {
+ // /private/prg/code/xreate/antlr/lisp.g:3:14: ( '\\t' | ' ' | '\\r' | '\\n' | '\\u000C' )+
+ int cnt1=0;
+ loop1:
+ do {
+ int alt1=2;
+ int LA1_0 = input.LA(1);
+
+ if ( ((LA1_0 >= '\t' && LA1_0 <= '\n')||(LA1_0 >= '\f' && LA1_0 <= '\r')||LA1_0==' ') ) {
+ alt1=1;
+ }
+
+
+ switch (alt1) {
+ case 1 :
+ // /private/prg/code/xreate/antlr/lisp.g:
+ {
+ if ( (input.LA(1) >= '\t' && input.LA(1) <= '\n')||(input.LA(1) >= '\f' && input.LA(1) <= '\r')||input.LA(1)==' ' ) {
+ input.consume();
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException(null,input);
+ recover(mse);
+ throw mse;
+ }
+
+
+ }
+ break;
+
+ default :
+ if ( cnt1 >= 1 ) break loop1;
+ EarlyExitException eee =
+ new EarlyExitException(1, input);
+ throw eee;
+ }
+ cnt1++;
+ } while (true);
+
+
+ _channel = HIDDEN;
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "WHITESPACE"
+
+ // $ANTLR start "WORD"
+ public final void mWORD() throws RecognitionException {
+ try {
+ int _type = WORD;
+ int _channel = DEFAULT_TOKEN_CHANNEL;
+ // /private/prg/code/xreate/antlr/lisp.g:5:6: ( ( 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' )+ )
+ // /private/prg/code/xreate/antlr/lisp.g:5:8: ( 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' )+
+ {
+ // /private/prg/code/xreate/antlr/lisp.g:5:8: ( 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' )+
+ int cnt2=0;
+ loop2:
+ do {
+ int alt2=2;
+ int LA2_0 = input.LA(1);
+
+ if ( ((LA2_0 >= '0' && LA2_0 <= '9')||(LA2_0 >= 'A' && LA2_0 <= 'Z')||LA2_0=='_'||input.LA(1)=='-'||(LA2_0 >= 'a' && LA2_0 <= 'z')) ) {
+ alt2=1;
+ }
+
+
+ switch (alt2) {
+ case 1 :
+ // /private/prg/code/xreate/antlr/lisp.g:
+ {
+ if ( (input.LA(1) >= '0' && input.LA(1) <= '9')||(input.LA(1) >= 'A' && input.LA(1) <= 'Z')||input.LA(1)=='_' ||input.LA(1)=='-' ||(input.LA(1) >= 'a' && input.LA(1) <= 'z') ) {
+ input.consume();
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException(null,input);
+ recover(mse);
+ throw mse;
+ }
+
+
+ }
+ break;
+
+ default :
+ if ( cnt2 >= 1 ) break loop2;
+ EarlyExitException eee =
+ new EarlyExitException(2, input);
+ throw eee;
+ }
+ cnt2++;
+ } while (true);
+
+
+ }
+
+ state.type = _type;
+ state.channel = _channel;
+ }
+ finally {
+ // do for sure before leaving
+ }
+ }
+ // $ANTLR end "WORD"
+
+ public void mTokens() throws RecognitionException {
+ // /private/prg/code/xreate/antlr/lisp.g:1:8: ( T__6 | T__7 | T__8 | WHITESPACE | WORD )
+ int alt3=5;
+ switch ( input.LA(1) ) {
+ case '(':
+ {
+ alt3=1;
+ }
+ break;
+ case ')':
+ {
+ alt3=2;
+ }
+ break;
+ case ',':
+ {
+ alt3=3;
+ }
+ break;
+ case '\t':
+ case '\n':
+ case '\f':
+ case '\r':
+ case ' ':
+ {
+ alt3=4;
+ }
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ case 'G':
+ case 'H':
+ case 'I':
+ case 'J':
+ case 'K':
+ case 'L':
+ case 'M':
+ case 'N':
+ case 'O':
+ case 'P':
+ case 'Q':
+ case 'R':
+ case 'S':
+ case 'T':
+ case 'U':
+ case 'V':
+ case 'W':
+ case 'X':
+ case 'Y':
+ case 'Z':
+ case '_':
+ case '-':
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ case 'g':
+ case 'h':
+ case 'i':
+ case 'j':
+ case 'k':
+ case 'l':
+ case 'm':
+ case 'n':
+ case 'o':
+ case 'p':
+ case 'q':
+ case 'r':
+ case 's':
+ case 't':
+ case 'u':
+ case 'v':
+ case 'w':
+ case 'x':
+ case 'y':
+ case 'z':
+ {
+ alt3=5;
+ }
+ break;
+ default:
+ NoViableAltException nvae =
+ new NoViableAltException("", 3, 0, input);
+
+ throw nvae;
+
+ }
+
+ switch (alt3) {
+ case 1 :
+ // /private/prg/code/xreate/antlr/lisp.g:1:10: T__6
+ {
+ mT__6();
+
+
+ }
+ break;
+ case 2 :
+ // /private/prg/code/xreate/antlr/lisp.g:1:15: T__7
+ {
+ mT__7();
+
+
+ }
+ break;
+ case 3 :
+ // /private/prg/code/xreate/antlr/lisp.g:1:20: T__8
+ {
+ mT__8();
+
+
+ }
+ break;
+ case 4 :
+ // /private/prg/code/xreate/antlr/lisp.g:1:25: WHITESPACE
+ {
+ mWHITESPACE();
+
+
+ }
+ break;
+ case 5 :
+ // /private/prg/code/xreate/antlr/lisp.g:1:36: WORD
+ {
+ mWORD();
+
+
+ }
+ break;
+
+ }
+
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/org/xreate/grammatic/lisp/LispParser.java b/src/main/java/org/xreate/grammatic/lisp/LispParser.java
new file mode 100644
index 0000000..19d8dea
--- /dev/null
+++ b/src/main/java/org/xreate/grammatic/lisp/LispParser.java
@@ -0,0 +1,145 @@
+package org.xreate.grammatic.lisp;
+
+// $ANTLR 3.4 /private/prg/code/xreate/antlr/lisp.g 2012-04-07 17:57:03
+
+import org.antlr.runtime.*;
+import java.util.Stack;
+import java.util.List;
+import java.util.ArrayList;
+
+@SuppressWarnings({"all", "warnings", "unchecked"})
+public class LispParser extends Parser {
+ public static final String[] tokenNames = new String[] {
+ "<invalid>", "<EOR>", "<DOWN>", "<UP>", "WHITESPACE", "WORD", "'('", "')'", "','"
+ };
+
+ public static final int EOF=-1;
+ public static final int T__6=6;
+ public static final int T__7=7;
+ public static final int T__8=8;
+ public static final int WHITESPACE=4;
+ public static final int WORD=5;
+
+ // delegates
+ public Parser[] getDelegates() {
+ return new Parser[] {};
+ }
+
+ // delegators
+
+
+ public LispParser(TokenStream input) {
+ this(input, new RecognizerSharedState());
+ }
+ public LispParser(TokenStream input, RecognizerSharedState state) {
+ super(input, state);
+ }
+
+ public String[] getTokenNames() { return LispParser.tokenNames; }
+ public String getGrammarFileName() { return "/private/prg/code/xreate/antlr/lisp.g"; }
+
+
+
+ // $ANTLR start "statement"
+ // /private/prg/code/xreate/antlr/lisp.g:7:1: statement : WORD ( '(' statement ( ',' statement )* ')' )? ;
+ public final ASTLispNode statement(ASTLispNode node) throws RecognitionException {
+ try {
+ // /private/prg/code/xreate/antlr/lisp.g:8:2: ( WORD ( '(' statement ( ',' statement )* ')' )? )
+ // /private/prg/code/xreate/antlr/lisp.g:8:4: WORD ( '(' statement ( ',' statement )* ')' )?
+ {
+ CommonToken token = (CommonToken) match(input,WORD,FOLLOW_WORD_in_statement71);
+
+ String text = token.getText();
+ ASTLispNode nodeChild = ('0' <= text.charAt(0) && '9'>= text.charAt(0))? new ASTLispConstantNode(text) : new ASTLispNode(text);
+ if (node != null){
+ node.add(nodeChild);
+ }
+ node = nodeChild;
+
+ // /private/prg/code/xreate/antlr/lisp.g:8:9: ( '(' statement ( ',' statement )* ')' )?
+ int alt2=2;
+ int LA2_0 = input.LA(1);
+
+ if ( (LA2_0==6) ) {
+ alt2=1;
+ }
+ switch (alt2) {
+ case 1 :
+ // /private/prg/code/xreate/antlr/lisp.g:8:10: '(' statement ( ',' statement )* ')'
+ {
+ match(input,6,FOLLOW_6_in_statement74);
+
+ pushFollow(FOLLOW_statement_in_statement76);
+ statement(node);
+
+ state._fsp--;
+
+
+ // /private/prg/code/xreate/antlr/lisp.g:8:24: ( ',' statement )*
+ loop1:
+ do {
+ int alt1=2;
+ int LA1_0 = input.LA(1);
+
+ if ( (LA1_0==8) ) {
+ alt1=1;
+ }
+
+
+ switch (alt1) {
+ case 1 :
+ // /private/prg/code/xreate/antlr/lisp.g:8:25: ',' statement
+ {
+ match(input,8,FOLLOW_8_in_statement79);
+
+ pushFollow(FOLLOW_statement_in_statement81);
+ statement(node);
+
+ state._fsp--;
+
+
+ }
+ break;
+
+ default :
+ break loop1;
+ }
+ } while (true);
+
+
+ match(input,7,FOLLOW_7_in_statement85);
+
+ }
+ break;
+
+ }
+
+
+ }
+
+ }
+ catch (RecognitionException re) {
+ reportError(re);
+ recover(input,re);
+ }
+
+ finally {
+ // do for sure before leaving
+ }
+ return node;
+ }
+ // $ANTLR end "statement"
+
+ // Delegated rules
+
+
+
+
+ public static final BitSet FOLLOW_WORD_in_statement71 = new BitSet(new long[]{0x0000000000000042L});
+ public static final BitSet FOLLOW_6_in_statement74 = new BitSet(new long[]{0x0000000000000020L});
+ public static final BitSet FOLLOW_statement_in_statement76 = new BitSet(new long[]{0x0000000000000180L});
+ public static final BitSet FOLLOW_8_in_statement79 = new BitSet(new long[]{0x0000000000000020L});
+ public static final BitSet FOLLOW_statement_in_statement81 = new BitSet(new long[]{0x0000000000000180L});
+ public static final BitSet FOLLOW_7_in_statement85 = new BitSet(new long[]{0x0000000000000002L});
+
+}
\ No newline at end of file
diff --git a/src/test/java/org/xreate/ASTTest1.java b/src/test/java/org/xreate/ASTTest1.java
new file mode 100644
index 0000000..c30c808
--- /dev/null
+++ b/src/test/java/org/xreate/ASTTest1.java
@@ -0,0 +1,55 @@
+package org.xreate;
+
+import com.google.common.collect.ListMultimap;
+import com.google.common.collect.Maps;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Map;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Unit test for simple App.
+ */
+public class ASTTest1
+ extends TestCase
+{
+ /**
+ * Create the test case
+ *
+ * @param testName name of the test case
+ */
+ public ASTTest1( String testName )
+ {
+ super( testName );
+ }
+
+ /**
+ * @return the suite of tests being tested
+ */
+ public static Test suite()
+ {
+ return new TestSuite( ASTTest1.class );
+ }
+
+ /**
+ * Rigourous Test :-)
+ */
+ public void testAST1() throws NoSuchMethodException, IllegalAccessException, Throwable
+ {
+ ASTVar x = new ASTVar();
+ ASTValue y = new ASTValue(10);
+ ASTAssignment as = new ASTAssignment();
+
+ as.var = x;
+ as.value = y;
+ ComputableAnalysis analysis = new ComputableAnalysis();
+ ASTNode result = as.acceptComputableVisitor(analysis);
+
+ assertTrue( true );
+ }
+}
+
+
+
diff --git a/src/test/java/org/xreate/LispTest.java b/src/test/java/org/xreate/LispTest.java
new file mode 100644
index 0000000..e9f7bc1
--- /dev/null
+++ b/src/test/java/org/xreate/LispTest.java
@@ -0,0 +1,69 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.xreate;
+
+import java.io.IOException;
+import junit.framework.TestCase;
+import org.antlr.runtime.*;
+import org.junit.Ignore;
+import org.xreate.grammatic.lisp.ASTLispNode;
+import org.xreate.grammatic.lisp.LispLexer;
+import org.xreate.grammatic.lisp.LispParser;
+
+import static org.junit.Assert.*;
+import org.junit.Test;
+import org.xreate.grammatic.lisp.LispInterpreter;
+/**
+ *
+ * @author pgess
+ */
+public class LispTest {
+ static int z;
+
+ @Ignore
+ @Test
+ public void test1() throws RecognitionException{
+ assertTrue(true);
+
+ ANTLRStringStream in = new ANTLRStringStream("aa(bb, cc(dd, ee))");
+
+ Lexer l = new LispLexer(in);
+ CommonTokenStream tokens = new CommonTokenStream(l);
+
+ LispParser p = new LispParser(tokens);
+
+ ASTLispNode node = p.statement(null);
+
+ int x = 0;
+ }
+
+ @Ignore
+ @Test
+ public void test2() throws IOException, RecognitionException{
+ ANTLRStringStream in = new ANTLRFileStream("/private/prg/code/xreate/scripts/opcode.li");
+
+ Lexer l = new LispLexer(in);
+ CommonTokenStream tokens = new CommonTokenStream(l);
+
+ LispParser p = new LispParser(tokens);
+
+ ASTLispNode node = p.statement(null);
+
+ int x = 0;
+ }
+
+ @Test
+ public void test3() throws Exception{
+ LispInterpreter lisp = new LispInterpreter();
+
+ lisp.run("/private/prg/code/xreate/scripts/opcode.li");
+
+ //assertEquals(answer, 100);
+ }
+
+ static {
+ System.loadLibrary("jllvm");
+ }
+}
Event Timeline
Log In to Comment