Permalink
Browse files

added functions and a short description

  • Loading branch information...
1 parent fc7dc76 commit 46ce1ed200187a7487005dd4301fd8b4f58de69e @thoefer2 thoefer2 committed Dec 6, 2012
Showing with 411 additions and 323 deletions.
  1. +5 −1 Ex1Test.g
  2. +66 −19 Ex1Walker.g
  3. +1 −1 Makefile
  4. +15 −3 README.md
  5. +21 −9 index.html
  6. +1 −1 main.js
  7. +302 −289 mocca-lang.js
View
@@ -7,6 +7,8 @@ options {
tokens {
FN_CALL;
+ FN_DEF;
+ EX;
}
@members {
@@ -17,7 +19,8 @@ prog: exprStmt* EOF -> exprStmt*
;
exprStmt: ID ':' expr ';' -> ^(':' ID expr)
- | ID e+=expr (':' e+=expr)* ';' -> ^(FN_CALL ID expr*)
+ | name=ID ':' (arg+=ID)? (',' arg+=ID)* '{' body+=exprStmt* '}' ';' -> ^(FN_DEF $name $arg* $body*)
+ | expr ';' -> ^(EX expr)
;
expr: (exprAnd -> exprAnd)
@@ -72,6 +75,7 @@ unary: atom
// doesn´t make much sense. Cases like this need to be catched in the semantic analysis phase.
atom: INTEGER
| ID
+ | ID '(' e+=expr? (',' e+=expr)* ')' -> ^(FN_CALL ID $e*)
| BOOLEAN
| '(' expr ')' -> expr
;
View
@@ -263,6 +263,33 @@ options {
};
};
+ L.FunctionDef = function(scope, id, localScope) {
+ this.scope = scope;
+ this.id = id;
+ this.args = [];
+ this.body = [];
+ this.localScope = localScope;
+ this.interpret = function() {
+ var that = this;
+ var sym = new L.SymVar(this.id, new L.Value({
+ args: this.args,
+ invoke: function(actualArgs) {
+ for(var i = 0; i < actualArgs.length; i++) {
+ that.localScope.define(new L.SymVar(that.args[i], actualArgs[i]));
+ }
+ var last;
+ for(i = 0; i < that.body.length; i++) {
+ var stmt = that.body[i];
+ last = stmt.interpret();
+ }
+ return last;
+ }
+ }, L.T.FN));
+ this.scope.define(sym);
+ return sym.value;
+ };
+ };
+
L.FunctionCall = function(scope, id) {
this.scope = scope;
this.id = id;
@@ -334,24 +361,39 @@ options {
this.value = value;
};
- this.currentScope = new L.Scope("global", undefined);
- this.currentScope.define(new L.SymVar("puts", new L.Value({
- args: [1],
- invoke: function(args) {
- var arg = args[0];
- console.debug(arg.toString());
- }
- }, L.T.FN)
- ));
- this.currentScope.define(new L.SymVar("assert", new L.Value({
- args: [1],
- invoke: function(args) {
- var arg = args[0];
- if(!arg.toBoolean() === true)
- throw new Error("AssertionError");
- }
- }, L.T.FN)
- ));
+ L.GlobalScope = function(){
+
+ L.Scope.call(this, "global", undefined);
+ this.define(new L.SymVar("puts", new L.Value({
+ args: [1],
+ invoke: function(args) {
+ var arg = args[0];
+ console.debug(arg.toString());
+ }
+ }, L.T.FN)
+ ));
+ this.define(new L.SymVar("assert", new L.Value({
+ args: [1],
+ invoke: function(args) {
+ var arg = args[0];
+ if(!arg.toBoolean() === true)
+ throw new Error("AssertionError");
+ }
+ }, L.T.FN)
+ ));
+
+ };
+ L.GlobalScope.prototype = L.Scope.prototype;
+ this.currentScope = new L.GlobalScope();
+ this.oldScope;
+ this.pushScope = function() {
+ this.oldScope = this.currentScope;
+ this.currentScope = new L.Scope("block", this.oldScope);
+ return this.currentScope;
+ };
+ this.popScope = function() {
+ this.currentScope = this.currentScope.getEnclosingScope();
+ };
}
@@ -363,7 +405,11 @@ prog returns [node]
exprStmt returns [node]
: ^(':' ID expr) { $node = new L.Assignment(this.currentScope, $ID.text, $expr.node); }
- | ^(FN_CALL ID {var node = new L.FunctionCall(this.currentScope, $ID.text);} (e=expr {node.addArgument($e.node);})*) { $node = node; }
+ | ^(FN_DEF name=ID {var node = new L.FunctionDef(this.currentScope, $name.text, this.pushScope()); } (arg=ID {node.args.push($arg.text);} )* (e=exprStmt { node.body.push($e.node); })* ) {
+ $node = node;
+ this.popScope();
+ }
+ | ^(EX expr) { $node = $expr.node; }
;
expr returns [node]
@@ -380,6 +426,7 @@ expr returns [node]
| ^('>=' a=expr b=expr) { $node = new L.Gte($a.node, $b.node); }
| ^('<=' a=expr b=expr) { $node = new L.Lte($a.node, $b.node); }
| ^('!' a=expr) { $node = new L.Negate($a.node); }
+ | ^(FN_CALL ID {var node = new L.FunctionCall(this.currentScope, $ID.text);} (e=expr {node.addArgument($e.node);})*) { $node = node; }
| i=INTEGER {
var valueInt = new L.Value($i.text, L.T.INT);
$node = new L.Literal(valueInt);
View
@@ -1,5 +1,5 @@
parser:
- export CLASSPATH=/Users/tom/tom/FHR/MA/code/bin/antlr-3.3-complete.jar:$$CLASSPATH && java org.antlr.Tool Ex1Test.g Ex1Walker.g && clear
+ export CLASSPATH=/Users/tom/tom/FHR/MA/code/bin/antlr-3.3-complete.jar:$$CLASSPATH && java org.antlr.Tool Ex1Test.g Ex1Walker.g
minify:
java -jar tools/compiler-latest/compiler.jar \
View
@@ -1,7 +1,19 @@
The Mocca Programming Language
==============================
-Too early for a precise description ;) See index.html for a few code
-samples. Basically it´s quite easy to get started: include mocca-lang.js
-and type your code in text/mocca script blocks.
+Actually to early for a precise description, but try it nonetheless:
+
+* int, boolean and function data types
+* expression evaluation respective correct precedence and associativity
+* variable definitions and usage in expressions
+* lexical scoping
+* functions behave like closures
+* a function call returns the last statement per default
+* a few semantic runtime checks
+
+No flow control structures atm.
+
+See index.html for a few code samples. Basically it´s quite easy to get started: include mocca-lang.js and type your code in text/mocca script blocks.
+
+
View
@@ -2,23 +2,35 @@
<html lang="en">
<head>
-<script type="text/javascript" src="mocca-lang.js"></script>
+<script type="text/javascript" src="antlr3-all.js"></script>
+<script type="text/javascript" src="Ex1TestLexer.js"></script>
+<script type="text/javascript" src="Ex1TestParser.js"></script>
+<script type="text/javascript" src="Ex1Walker.js"></script>
+<script type="text/javascript" src="jquery-1.8.3.min.js"></script>
+<script type="text/javascript" src="main.js"></script>
+
<script type="text/mocca">
five: 5;
six: 6;
- truth: T;
- assert five == 5 && six == 6 && truth == T;
result1: (five+five)*2 == six + 7 * 2;
- assert result1;
result2: five < six;
- assert result2;
allTrue: 6 <= 6 || T == F || F || (result1 == result2 && result2 == result1 && (five - six * 2 + 200) < six || F);
- assert allTrue;
- puts !!!!!!!!!!!!!!(!!!!!!!(((((((five + six >= 11) && allTrue && T)))))));
- puts 34;
-
+ abc: !!!!!!!!!!!!!!(!!!!!!!(((((((five + six >= 11) && allTrue && T)))))));
+ someFn: op1, op2 {
+ two: 2;
+ innerFn: arg {
+ op1 + op2 + two * two + arg;
+ };
+ anotherFn: ten {
+ innerFn(ten) * 2;
+ };
+ };
+ fnResult: someFn(77, 9);
+ assert(fnResult(10) == 200);
+
+
</script>
View
@@ -11,7 +11,7 @@
var nodes = new org.antlr.runtime.tree.CommonTreeNodeStream(r.getTree());
nodes.setTokenStream(tstream);
- var walker = new Ex1Walker(nodes);
+ walker = new Ex1Walker(nodes);
walker.prog().interpret();
});
Oops, something went wrong.

0 comments on commit 46ce1ed

Please sign in to comment.