Skip to content

Commit

Permalink
Initial skeleton
Browse files Browse the repository at this point in the history
  • Loading branch information
tvdstorm committed Nov 13, 2018
1 parent 18e7c40 commit 893a564
Show file tree
Hide file tree
Showing 20 changed files with 610 additions and 0 deletions.
7 changes: 7 additions & 0 deletions .classpath
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/bin/
40 changes: 40 additions & 0 deletions .project
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>QL</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>rascal_eclipse.rascal_builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>rascal_eclipse.term_builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>rascal_eclipse.rascal_nature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>rascal_eclipse.term_nature</nature>
</natures>
</projectDescription>
7 changes: 7 additions & 0 deletions META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: QL
Bundle-SymbolicName: QL
Bundle-Version: 1.0.0
Require-Bundle: rascal_eclipse
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
6 changes: 6 additions & 0 deletions META-INF/RASCAL.MF
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Manifest-Version: 0.0.1
Main-Function: main
Courses: courses
Main-Module: IDE
Source: src

1 change: 1 addition & 0 deletions build.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bin.includes = META-INF/
111 changes: 111 additions & 0 deletions examples/binary.tql
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
form binary {
"Is the number between 1 and 10" x_1_10: boolean
if (x_1_10) {
"Is the number between 1 and 5" x_1_5: boolean
if (x_1_5) {
"Is the number between 1 and 3" x_1_3: boolean
if (x_1_3) {
"Is the number between 1 and 2" x_1_2: boolean
if (x_1_2) {
"The answer is" answer_1_2: integer = (1)
}
else {
"The answer is" answer_2_3: integer = (2)
}
}
else {
"Is the number between 3 and 4" x_3_4: boolean
if (x_3_4) {
"The answer is" answer_3_4: integer = (3)
}
else {
"The answer is" answer_4_5: integer = (4)
}
}
}
else {
"Is the number between 5 and 7" x_5_7: boolean
if (x_5_7) {
"Is the number between 5 and 6" x_5_6: boolean
if (x_5_6) {
"The answer is" answer_5_6: integer = (5)
}
else {
"The answer is" answer_6_7: integer = (6)
}
}
else {
"Is the number between 7 and 8" x_7_8: boolean
if (x_7_8) {
"The answer is" answer_7_8: integer = (7)
}
else {
"Is the number between 8 and 9" x_8_9: boolean
if (x_8_9) {
"The answer is" answer_8_9: integer = (8)
}
else {
"The answer is" answer_9_10: integer = (9)
}
}
}
}
}
else {
"Is the number between 10 and 15" x_10_15: boolean
if (x_10_15) {
"Is the number between 10 and 12" x_10_12: boolean
if (x_10_12) {
"Is the number between 10 and 11" x_10_11: boolean
if (x_10_11) {
"The answer is" answer_10_11: integer = (10)
}
else {
"The answer is" answer_11_12: integer = (11)
}
}
else {
"Is the number between 12 and 13" x_12_13: boolean
if (x_12_13) {
"The answer is" answer_12_13: integer = (12)
}
else {
"Is the number between 13 and 14" x_13_14: boolean
if (x_13_14) {
"The answer is" answer_13_14: integer = (13)
}
else {
"The answer is" answer_14_15: integer = (14)
}
}
}
}
else {
"Is the number between 15 and 17" x_15_17: boolean
if (x_15_17) {
"Is the number between 15 and 16" x_15_16: boolean
if (x_15_16) {
"The answer is" answer_15_16: integer = (15)
}
else {
"The answer is" answer_16_17: integer = (16)
}
}
else {
"Is the number between 17 and 18" x_17_18: boolean
if (x_17_18) {
"The answer is" answer_17_18: integer = (17)
}
else {
"Is the number between 18 and 19" x_18_19: boolean
if (x_18_19) {
"The answer is" answer_18_19: integer = (18)
}
else {
"The answer is" answer_19_20: integer = (19)
}
}
}
}
}
}
24 changes: 24 additions & 0 deletions examples/cyclic.tql
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
form taxOfficeExample {
"Did you buy a house in 2010?"
hasBoughtHouse: boolean

"Did you enter a loan?"
hasMaintLoan: boolean

if (hasSoldHouse) {
"What was the selling price?"
sellingPrice: money = valueResidue
"Private debts for the sold house:"
privateDebt: money
"Value residue:"
valueResidue: money =
((sellingPrice - privateDebt) * 2)
}

if (privateDebt > 0) {
"Did you sell a house in 2010?"
hasSoldHouse: boolean
}


}
3 changes: 3 additions & 0 deletions examples/empty.tql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
form taxOfficeExample {

}
20 changes: 20 additions & 0 deletions examples/errors.tql
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
form taxOfficeExample {
"Did you buy a house in 2010?"
hasBoughtHouse: boolean

"Did you enter a loan?"
hasMaintLoan: boolean

"Did you sell a house in 2010?"
hasSoldHouse: boolean

if (hasSodHouse) {
"What was the selling price?"
sellingPrice: boolean
"Private debts for the sold house:"
privateDebt: money
"Value residue:"
valueResidue: money =
((sellingPrice - privateDebt) * true)
}
}
23 changes: 23 additions & 0 deletions examples/tax.tql
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
form taxOfficeExample {
"Did you buy a house in 2010?"
hasBoughtHouse: boolean


// akjsdhakjshdkjsa

"Did you enter a loan?"
hasMaintLoan: boolean

"Did you sell a house in 2010?"
hasSoldHouse: boolean

if (hasSoldHouse) {
"What was the selling price?"
sellingPrice: money
"Private debts for the sold house:"
privateDebt: money
"Value residue:"
valueResidue: money = sellingPrice - privateDebt

}
}
19 changes: 19 additions & 0 deletions src/AST.rsc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module AST

/*
* Define Abstract Syntax for QL
*
* - complete the following data types
* - make sure there is an almost one-to-one correspondence with the grammar
*/

data AForm(loc src = |unknown://|)
= form(str name, list[AQuestion] questions)
;

data AQuestion(loc src = |unknown://|);

data AExpr(loc src = |unknown://|)
= ref(str name);


34 changes: 34 additions & 0 deletions src/CST2AST.rsc
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
module CST2AST

import Syntax;
import AST;
import ParseTree;
import String;

/*
* Implement a mapping from concrete syntax trees (CSTs) to abstract syntax trees (ASTs)
*
* - Use switch to do case distinction with concrete patterns (like in Hack your JS)
* - Map regular CST arguments (e.g., *, +, ?) to lists
* (NB: you can iterate over * / + arguments using `<-` in comprehensions or for-loops).
* - Map lexical nodes to Rascal primitive types (bool, int, str)
* - See the ref example on how to obtain and propagate source locations.
*/

AForm cst2ast(start[Form] f) {
return form("", []); // TODO
}

AQuestion cst2ast(Question q) {
// TODO
}

AExpr cst2ast(Expr e) {
switch (e) {
case (Expr)`<Id x>`: return ref("<x>", src=x@\loc);

// ...

default: throw "Unhandled expression: <e>";
}
}
74 changes: 74 additions & 0 deletions src/Check.rsc
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
module Check

import AST;
import Resolve;
import Message; // see standard library

data Type
= tint()
| tbool()
| tstr()
| tunknown()
;

// the type environment consisting of defined questions in the form
alias TEnv = rel[loc def, str name, str label, Type \type];

// To avoid recursively traversing the form, use the `visit` construct
// or deep match (e.g., `for (/question(...) := f) {...}` )
TEnv collect(AForm f) {
return {}; // TODO
}

set[Message] check(AForm f, TEnv tenv, UseDef useDef) {
return {}; // TODO
}

// - produce an error if there are declared questions with the same name but different types.
// - duplicate labels should trigger a warning
// - the declared type computed questions should match the type of the expression.
set[Message] check(AQuestion q, TEnv tenv, UseDef useDef) {
return {}; // TODO
}

// Check operand compatibility with operators.
// E.g. for an addition node add(lhs, rhs),
// the requirement is that typeOf(lhs) == typeOf(rhs) == tint()
set[Message] check(AExpr e, TEnv tenv, UseDef useDef) {
set[Message] msgs = {};

switch (e) {
case ref(str x, src = loc u):
msgs += { error("Undeclared question", u) | useDef[u] == {} };

// etc.
}

return msg;
}

Type typeOf(AExpr e, TEnv tenv, UseDef useDef) {
switch (e) {
case ref(str x, src = loc u):
if (<u, loc d> <- useDef, <d, x, _, Type t> <- tenv) {
return t;
}

}
return tunknown(); // TODO
}

/*
* Pattern-based dispatch style:
*
* Type typeOf(ref(str x, src = loc u), TEnv tenv, UseDef useDef) = t
* when <u, loc d> <- useDef, <d, x, _, Type t> <- tenv
*
* ... etc.
*
* default Type typeOf(AExpr _, TEnv _, UseDef _) = tunknown();
*
*/



Loading

0 comments on commit 893a564

Please sign in to comment.