Skip to content

Commit

Permalink
simplify syntax for parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
yinwang0 committed Jan 31, 2014
1 parent 532d00a commit f7c3f96
Show file tree
Hide file tree
Showing 12 changed files with 182 additions and 71 deletions.
4 changes: 2 additions & 2 deletions src/main/java/org/yinwang/yin/Binder.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public static void define(Node pattern, Value value, Scope env) {
if (v != null) {
_.abort(pattern, "trying to redefine name: " + id);
} else {
env.put(id, value);
env.putValue(id, value);
}
} else if (pattern instanceof RecordLiteral) {
if (value instanceof RecordType) {
Expand Down Expand Up @@ -66,7 +66,7 @@ public static void assign(Node pattern, Value value, Scope env) {
if (d == null) {
_.abort(pattern, "assigned name was not defined: " + id);
} else {
d.put(id, value);
d.putValue(id, value);
}
} else if (pattern instanceof Subscript) {
((Subscript) pattern).set(value, env);
Expand Down
92 changes: 69 additions & 23 deletions src/main/java/org/yinwang/yin/Scope.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@
import org.yinwang.yin.value.primitives.*;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

public class Scope {

public Map<String, Value> table = new HashMap<>();
public Map<String, Map<String, Object>> table = new HashMap<>();
public Scope parent;


Expand All @@ -27,24 +28,59 @@ public Scope(Scope parent) {


public Value lookupLocal(String name) {
return table.get(name);
Object v = lookupLocalItem(name, "value");
if (v == null) {
return null;
} else if (v instanceof Value) {
return (Value) v;
} else {
_.abort("value is not a Value, shouldn't happen: " + v);
return null;
}
}


public Value lookup(String name) {
Value v = table.get(name);
Object v = lookupLocalItem(name, "value");
if (v == null) {
if (parent != null) {
return parent.lookup(name);
} else {
return null;
}
} else if (v instanceof Value) {
return (Value) v;
} else {
_.abort("value is not a Value, shouldn't happen: " + v);
return null;
}
}


public Object lookupLocalItem(String name, String key) {
Map<String, Object> item = table.get(name);
if (item != null) {
return item.get(key);
} else {
return null;
}
}


public Object lookupItem(String name, String key) {
Object v = lookupLocalItem(name, key);
if (v != null) {
return v;
} else if (parent != null) {
return parent.lookup(name);
return parent.lookupItem(name, key);
} else {
return null;
}
}


public Scope findDefiningScope(String name) {
Value v = table.get(name);
Object v = table.get(name);
if (v != null) {
return this;
} else if (parent != null) {
Expand All @@ -58,32 +94,42 @@ public Scope findDefiningScope(String name) {
public static Scope buildInitScope() {
Scope init = new Scope();

init.put("+", new Add());
init.put("-", new Sub());
init.put("*", new Mult());
init.put("/", new Div());
init.putValue("+", new Add());
init.putValue("-", new Sub());
init.putValue("*", new Mult());
init.putValue("/", new Div());

init.put("<", new Lt());
init.put("<=", new LtE());
init.put(">", new Gt());
init.put(">=", new GtE());
init.put("=", new Eq());
init.put("and", new And());
init.put("or", new Or());
init.put("not", new Not());
init.putValue("<", new Lt());
init.putValue("<=", new LtE());
init.putValue(">", new Gt());
init.putValue(">=", new GtE());
init.putValue("=", new Eq());
init.putValue("and", new And());
init.putValue("or", new Or());
init.putValue("not", new Not());

init.put("true", new BoolValue(true));
init.put("false", new BoolValue(false));
init.putValue("true", new BoolValue(true));
init.putValue("false", new BoolValue(false));

init.put("Int", new IntType());
init.put("Bool", new BoolType());
init.putValue("Int", new IntType());
init.putValue("Bool", new BoolType());

return init;
}


public void put(String name, Value value) {
table.put(name, value);
public void put(String name, String key, Object value) {
Map<String, Object> item = table.get(name);
if (item == null) {
item = new LinkedHashMap<>();
}
item.put(key, value);
table.put(name, item);
}


public void putValue(String name, Object value) {
put(name, "value", value);
}

}
20 changes: 7 additions & 13 deletions src/main/java/org/yinwang/yin/ast/Call.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ public Value interp(Scope s) {
if (func instanceof Closure) {
Closure closure = (Closure) func;
Scope funScope = new Scope(closure.env);
Parameter params = closure.fun.params;
List<Name> params = closure.fun.params;

if (!args.positional.isEmpty() && args.keywords.isEmpty()) {
// positional
if (args.positional.size() == params.positional.size()) {
if (args.positional.size() == params.size()) {
for (int i = 0; i < args.positional.size(); i++) {
Value value = args.positional.get(i).interp(s);
Binder.define(params.positional.get(i), value, funScope);
Binder.define(params.get(i), value, funScope);
}
return closure.fun.body.interp(funScope);
} else {
Expand All @@ -49,21 +49,15 @@ public Value interp(Scope s) {
Set<String> seen = new HashSet<>();

// try to bind all arguments
for (Name param : params.positional) {

for (Name param : params) {
Node actual = args.keywords.get(param.id);
if (actual != null) {
seen.add(param.id);
Value value = actual.interp(funScope);
funScope.put(param.id, value);
funScope.putValue(param.id, value);
} else {
Value defaultValue = closure.defaults.get(param.id);
if (defaultValue != null) {
funScope.put(param.id, defaultValue);
} else {
_.abort(param, "argument not supplied for: " + param);
return Value.VOID;
}
_.abort(param, "argument not supplied for: " + param);
return Value.VOID;
}
}

Expand Down
14 changes: 4 additions & 10 deletions src/main/java/org/yinwang/yin/ast/Fun.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,22 @@
import org.yinwang.yin.value.Closure;
import org.yinwang.yin.value.Value;

import java.util.HashMap;
import java.util.Map;
import java.util.List;

public class Fun extends Node {
public Parameter params;
public List<Name> params;
public Node body;


public Fun(Parameter params, Node body, String file, int start, int end, int line, int col) {
public Fun(List<Name> params, Node body, String file, int start, int end, int line, int col) {
super(file, start, end, line, col);
this.params = params;
this.body = body;
}


public Value interp(Scope s) {
Map<String, Value> defaults = new HashMap<>();
for (Map.Entry<String, Node> e : params.valueMap.entrySet()) {
Value v = e.getValue().interp(s);
defaults.put(e.getKey(), v);
}
return new Closure(this, defaults, s);
return new Closure(this, s);
}


Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/yinwang/yin/ast/RecordDef.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public Value interp(Scope s) {
}

Value r = new RecordType(name.id, tm, vm, this);
s.put(name.id, r);
s.putValue(name.id, r);
return Value.VOID;
}

Expand Down
3 changes: 2 additions & 1 deletion src/main/java/org/yinwang/yin/ast/Str.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@


import org.yinwang.yin.Scope;
import org.yinwang.yin.value.StringValue;
import org.yinwang.yin.value.Value;

public class Str extends Node {
Expand All @@ -15,7 +16,7 @@ public Str(String value, String file, int start, int end, int line, int col) {


public Value interp(Scope s) {
return null;
return new StringValue(value);
}


Expand Down
39 changes: 36 additions & 3 deletions src/main/java/org/yinwang/yin/parser/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
import org.yinwang.yin.ast.*;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class Parser {

Expand Down Expand Up @@ -81,13 +83,22 @@ public static Node parseNode(Node prenode) {
if (tuple.elements.size() >= 3) {
Node preParams = tuple.elements.get(1);
if (preParams instanceof Tuple) {
Parameter parameter = new Parameter(((Tuple) preParams).elements);
List<Node> params = parseList(((Tuple) preParams).elements);
List<Name> paramNames = new ArrayList<>();
for (Node p : params) {
if (p instanceof Name) {
paramNames.add((Name) p);
} else {
_.abort(p, "parameter msut be a name");
return null;
}
}
List<Node> statements = parseList(tuple.elements.subList(2, tuple.elements.size()));
int start = statements.get(0).start;
int end = statements.get(statements.size() - 1).end;
Node body = new Block(statements, prenode.file, start, end, prenode.line, prenode.col);
return new Fun(parameter, body, prenode.file, prenode.start, prenode.end, prenode.line,
prenode.col);
return new Fun(paramNames, body, prenode.file, prenode.start, prenode.end,
prenode.line, prenode.col);
} else {
_.abort(preParams, "incorrect format of parameters");
}
Expand Down Expand Up @@ -176,6 +187,28 @@ public static List<Node> parseList(List<Node> prenodes) {
}


// treat the list of nodes as key-value pairs like (:x 1 :y 2)
public static Map<String, Node> parseMap(List<Node> prenodes) {
Map<String, Node> ret = new LinkedHashMap<>();
if (prenodes.size() % 2 != 0) {
_.abort("list must be of the form (:key1 value1 :key2 value2)");
return null;
}

for (int i = 0; i < prenodes.size(); i += 2) {
Node key = parseNode(prenodes.get(i));
Node value = parseNode(prenodes.get(i + 1));
if (!(key instanceof Keyword)) {
_.abort(key, "key must be a keyword, but got: " + key);
return null;
} else {
ret.put(((Keyword) key).id, value);
}
}
return ret;
}


public static Node groupAttr(Node prenode) {
if (prenode instanceof Tuple) {
Tuple t = (Tuple) prenode;
Expand Down
6 changes: 1 addition & 5 deletions src/main/java/org/yinwang/yin/value/Closure.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,14 @@
import org.yinwang.yin.Scope;
import org.yinwang.yin.ast.Fun;

import java.util.Map;

public class Closure extends Value {

public Fun fun;
public Map<String, Value> defaults;
public Scope env;


public Closure(Fun fun, Map<String, Value> defaults, Scope env) {
public Closure(Fun fun, Scope env) {
this.fun = fun;
this.defaults = defaults;
this.env = env;
}

Expand Down
18 changes: 14 additions & 4 deletions src/main/java/org/yinwang/yin/value/StringValue.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
package org.yinwang.yin.value;

/**
* Created by yinwang on 1/27/14.
*/
public class StringValue {

public class StringValue extends Value {
public String value;


public StringValue(String value) {
this.value = value;
}


public String toString() {
return "\"" + value + "\"";
}

}
15 changes: 12 additions & 3 deletions tests/types.yin
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,18 @@
(B :y 20 :z 30)


(define f
(fun ([:x (U Int Float) (+ 1 2)]
[:y Int])
(define f
(fun ([:x (U Int Float) (+ 1 2)]
[:y Int])
(+ x y)))

(f :y 2)

(define 我是
(fun ([:x Int] [:n Int])
["我是" x n]))

(define 三 3)

(我是 "猪头" 三)

Loading

0 comments on commit f7c3f96

Please sign in to comment.