Commit f564e531 authored by Andre Lipke's avatar Andre Lipke

Initial commit

parents
# Files and directories created by pub
.packages
.pub/
build/
# Remove the following pattern if you wish to check in your lock file
pubspec.lock
# Directory created by dartdoc
doc/api/
<component name="libraryTable">
<library name="Dart Packages" type="DartPackagesLibraryType">
<properties>
<option name="packageNameToDirsMap">
<entry key="analyzer">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/analyzer-0.27.6/lib" />
</list>
</value>
</entry>
<entry key="args">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/args-0.13.7/lib" />
</list>
</value>
</entry>
<entry key="async">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/async-1.13.2/lib" />
</list>
</value>
</entry>
<entry key="barback">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/barback-0.15.2+11/lib" />
</list>
</value>
</entry>
<entry key="charcode">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/charcode-1.1.1/lib" />
</list>
</value>
</entry>
<entry key="collection">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/collection-1.14.0/lib" />
</list>
</value>
</entry>
<entry key="convert">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/convert-2.0.1/lib" />
</list>
</value>
</entry>
<entry key="crypto">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/crypto-2.0.1/lib" />
</list>
</value>
</entry>
<entry key="csslib">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/csslib-0.13.5/lib" />
</list>
</value>
</entry>
<entry key="glob">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/glob-1.1.3/lib" />
</list>
</value>
</entry>
<entry key="html">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/html-0.13.1/lib" />
</list>
</value>
</entry>
<entry key="isolate">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/isolate-0.2.3/lib" />
</list>
</value>
</entry>
<entry key="logging">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/logging-0.11.3+1/lib" />
</list>
</value>
</entry>
<entry key="matcher">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.1/lib" />
</list>
</value>
</entry>
<entry key="package_config">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/package_config-1.0.1/lib" />
</list>
</value>
</entry>
<entry key="path">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/path-1.4.1/lib" />
</list>
</value>
</entry>
<entry key="plugin">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/plugin-0.2.0/lib" />
</list>
</value>
</entry>
<entry key="pool">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/pool-1.3.0/lib" />
</list>
</value>
</entry>
<entry key="quiver">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/quiver-0.25.0/lib" />
</list>
</value>
</entry>
<entry key="serialization">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/serialization-0.10.4+4/lib" />
</list>
</value>
</entry>
<entry key="source_span">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/source_span-1.3.1/lib" />
</list>
</value>
</entry>
<entry key="stack_trace">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.7.3/lib" />
</list>
</value>
</entry>
<entry key="string_scanner">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.0.1/lib" />
</list>
</value>
</entry>
<entry key="typed_data">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/typed_data-1.1.3/lib" />
</list>
</value>
</entry>
<entry key="utf">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/utf-0.9.0+3/lib" />
</list>
</value>
</entry>
<entry key="watcher">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/watcher-0.9.7+3/lib" />
</list>
</value>
</entry>
<entry key="yaml">
<value>
<list>
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/yaml-2.1.12/lib" />
</list>
</value>
</entry>
</option>
</properties>
<CLASSES>
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/analyzer-0.27.6/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/args-0.13.7/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/async-1.13.2/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/barback-0.15.2+11/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/charcode-1.1.1/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/collection-1.14.0/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/convert-2.0.1/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/crypto-2.0.1/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/csslib-0.13.5/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/glob-1.1.3/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/html-0.13.1/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/isolate-0.2.3/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/logging-0.11.3+1/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.1/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/package_config-1.0.1/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/path-1.4.1/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/plugin-0.2.0/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/pool-1.3.0/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/quiver-0.25.0/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/serialization-0.10.4+4/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/source_span-1.3.1/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.7.3/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.0.1/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/typed_data-1.1.3/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/utf-0.9.0+3/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/watcher-0.9.7+3/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/yaml-2.1.12/lib" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>
\ No newline at end of file
<component name="libraryTable">
<library name="Dart SDK">
<CLASSES>
<root url="file:///usr/lib/dart/lib/async" />
<root url="file:///usr/lib/dart/lib/collection" />
<root url="file:///usr/lib/dart/lib/convert" />
<root url="file:///usr/lib/dart/lib/core" />
<root url="file:///usr/lib/dart/lib/developer" />
<root url="file:///usr/lib/dart/lib/html" />
<root url="file:///usr/lib/dart/lib/indexed_db" />
<root url="file:///usr/lib/dart/lib/io" />
<root url="file:///usr/lib/dart/lib/isolate" />
<root url="file:///usr/lib/dart/lib/js" />
<root url="file:///usr/lib/dart/lib/js_util" />
<root url="file:///usr/lib/dart/lib/math" />
<root url="file:///usr/lib/dart/lib/mirrors" />
<root url="file:///usr/lib/dart/lib/svg" />
<root url="file:///usr/lib/dart/lib/typed_data" />
<root url="file:///usr/lib/dart/lib/web_audio" />
<root url="file:///usr/lib/dart/lib/web_gl" />
<root url="file:///usr/lib/dart/lib/web_sql" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager">
<output url="file://$PROJECT_DIR$/out" />
</component>
<component name="masterDetails">
<states>
<state key="ProjectJDKs.UI">
<settings>
<splitter-proportions>
<option name="proportions">
<list>
<option value="0.2" />
</list>
</option>
</splitter-proportions>
</settings>
</state>
</states>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/bfexpr.iml" filepath="$PROJECT_DIR$/bfexpr.iml" />
</modules>
</component>
</project>
\ No newline at end of file
This diff is collapsed.
analyzer:
strong-mode: true
# exclude:
# - path/to/excluded/files/**
# Lint rules and documentation, see http://dart-lang.github.io/linter/lints
linter:
rules:
- cancel_subscriptions
- close_sinks
- hash_and_equals
- iterable_contains_unrelated_type
- list_remove_unrelated_type
- test_types_in_equals
- unrelated_type_equality_checks
- valid_regexps
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.pub" />
<excludeFolder url="file://$MODULE_DIR$/bin/packages" />
<excludeFolder url="file://$MODULE_DIR$/build" />
<excludeFolder url="file://$MODULE_DIR$/packages" />
</content>
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Dart SDK" level="project" />
<orderEntry type="library" name="Dart Packages" level="project" />
</component>
</module>
\ No newline at end of file
abstract class AST {
int setPos = -1;
AST parent;
int get pos => setPos == -1 ? parent.pos : setPos;
}
abstract class Statement extends AST {
Reference getRef() => null;
}
class Create extends Statement {
Reference ref = new TempReference();
Reference getRef() => ref;
}
class CreateCopy extends Create {
CreateCopy(this.copy);
Reference copy;
}
class ClassCreate extends Create {
ClassCreate(this.name);
String name;
}
class IntCreate extends Create {
IntCreate(this.cells);
int cells;
}
class Block extends Statement {
Block({this.code, this.isContext = false}) {
if (code == null) code = [];
}
List<Statement> code;
Reference getRef() => code.length == 0 ? null : code.last.getRef();
bool isContext = false;
}
abstract class Reference extends Statement {
Reference getRef() => this;
List<Index> indexes;
}
class TempReference extends Reference {
TempReference() {
id = this.hashCode;
}
int id;
}
class NamedReference extends Reference {
NamedReference(this.name);
String name;
}
abstract class Index {}
class IntIndex extends Index {
IntIndex(this.ref, this.index);
Reference ref;
int index;
}
class MemberIndex extends Index {
MemberIndex(this.ref, this.name);
Reference ref;
String name;
}
abstract class Transform extends Statement {
Transform(this.source, this.targets);
Reference source;
List<Reference> targets;
Reference getRef() => targets.last;
}
class MoveTransform extends Transform {
MoveTransform(source, tgt) : super(source, tgt);
}
class CopyTransform extends Transform {
CopyTransform(source, tgt, [this.temp]) : super(source, tgt);
Reference temp;
}
class NotTransform extends Transform {
NotTransform(source, tgt) : super(source, tgt);
}
class NotCopyTransform extends Transform {
NotCopyTransform(source, tgt, [this.temp]) : super(source, tgt);
Reference temp;
}
class While extends Statement {
While(this.val, this.block);
Block block;
Reference val;
Reference getRef() => val;
}
class If extends Statement {
If(this.val, this.block);
Block block;
Reference val;
Reference getRef() => val;
}
class Modifier extends Statement {
Modifier(this.val);
Reference val;
Reference getRef() => val;
}
class AddModifier extends Modifier {
AddModifier(val, this.amount) : super(val);
int amount;
}
class SetModifier extends Modifier {
SetModifier(val, this.amount) : super(val);
int amount;
}
class Def extends Statement {
Def(this.ref);
NamedReference ref;
Reference getRef() => ref;
}
class VarDef extends Def {
VarDef(this.alias, ref) : super(ref);
Reference alias;
}
class LambdaDef extends Def {
LambdaDef(this.code, this.params, ref) : super(ref) {
ret = code.getRef();
}
List<String> params;
Statement code;
Reference ret;
}
class Call extends Statement {
Call(this.func, this.params);
List<Reference> params;
Reference func;
Reference ref = new TempReference();
Reference getRef() => ref;
}
\ No newline at end of file
import 'im.dart';
import 'compile.dart';
import 'main.dart';
Map<String, Builtin> builtins = {
"putc": (List<Var> params, IMNode p) {
if (params.length != 1) throw new CompilerError("Wrong number of arguments to putc");
p.children.add(new IO(p, params[0], false));
return params[0];
},
"getc": (List<Var> params, IMNode p) {
if (params.length != 1) throw new CompilerError("Wrong number of arguments to getc");
p.children.add(new IO(p, params[0], true));
return params[0];
},
};
\ No newline at end of file
import 'main.dart';
import 'im.dart' as im;
import 'ast.dart' as ast;
import 'simplify.dart' as resolve;
import 'builtin.dart';
reParent(im.IMNode n, im.IMNode p) {
n.parent = p;
n.children.forEach((im.IMNode c) => reParent(c, n));
}
compileAST(ast.AST rootAST) {
im.IMNode root = new im.Block(null, []);
root.setContext = new im.Context();
var baseWindow = new im.Window(root.context);
builtins.forEach((name, builtin) {
new im.CtxSymbol(baseWindow, new im.Var(new im.BuiltinType(builtin), "_builtin_" + name), name);
});
Map<String, int> names = {};
//var nnum = 0;
String getName(String name) {
//name = name.replaceAllMapped(new RegExp(r"[^A-Za-z0-9]"), (m) => "_");
name = name.substring(0, 1);
var i = names.putIfAbsent(name, () => 0);
names[name]++;
return name + "$i";
}
Map<ast.TempReference, List<im.Var>> tempMap = {};
Map<ast.TempReference, List<im.Var>> tempCtxSave() {
var out = new Map<ast.TempReference, List<im.Var>>();
tempMap.forEach((k, v) => out[k] = new List.from(v));
return out;
}
im.Var resolveVar(ast.Reference ref, im.Window w) {
if (ref is ast.TempReference) {
if (!tempMap.containsKey(ref)) throw new CompilerError("Temporary ${ref.id} referenced before its created");
return tempMap[ref].last;
} else if (ref is ast.NamedReference) {
return w.requireSymbol(ref.name).ref;
}
throw "Unknown ref type ${ref.runtimeType}";
}
void compile(ast.AST astn, im.IMNode node, [im.Window w]) {
var window = w ?? node.window;
if (astn is ast.Block) {
var cnode = new im.Block(node, []);
cnode.setWindow = w;
node.children.add(cnode);
if (astn.isContext) {
cnode.setContext = new im.Context(cnode.window);
astn.code.forEach((ast.Statement s) {
s.parent = astn;
compile(s, cnode, new im.Window(cnode.context));
});
} else {
astn.code.forEach((ast.Statement s) {
s.parent = astn;
compile(s, cnode);
});
}
} else if (astn is ast.CreateCopy) {
var copy = resolveVar(astn.copy, window);
im.Var x = new im.Var(copy.type, getName(copy.type.toString()));
tempMap.putIfAbsent(astn.ref, () => []).add(x);
} else if (astn is ast.ClassCreate) {
im.BaseType tpe = window.requireSymbol(astn.name).ref.type;
if (tpe is! im.TypeType) {
throw new CompilerError("Typedef expected, got $tpe");
}
im.Var x = new im.Var((tpe as im.TypeType).type, getName(tpe.toString()));
tempMap.putIfAbsent(astn.ref, () => []).add(x);
} else if (astn is ast.IntCreate) {
if (astn.cells <= 0) {
throw new CompilerError("Invalid number of cells");
}
im.IntType tpe = new im.IntType(astn.cells);
im.Var x = new im.Var(tpe, getName(tpe.toString()));
tempMap.putIfAbsent(astn.ref, () => []).add(x);
} else if (astn is ast.AddModifier) {
var cnode = new im.Modifier(node, resolveVar(astn.val, window), astn.amount);
cnode.setWindow = w;
node.children.add(cnode);
} else if (astn is ast.VarDef) {
im.Var alias = resolveVar(astn.alias, window);
window.context.localSymbols.add(new im.CtxSymbol(window, alias, astn.ref.name));
} else if (astn is ast.LambdaDef) {
im.Var x = new im.Var(new im.LambdaType(astn.code, window, astn.params), astn.ref.name);
window.context.localSymbols.add(new im.CtxSymbol(window, x, astn.ref.name));
} else if (astn is ast.Call) {
var cnode = new im.Block(node, []);
node.children.add(cnode);
im.Var v = resolveVar(astn.func, window);
if (v.type is! im.LambdaType && v.type is! im.BuiltinType) {
throw new CompilerError("Lambda or Builtin expected, got ${v.type}");
}
cnode.setContext = new im.Context(window);
im.Window baseWindow = new im.Window(cnode.context);
if (v.type is im.LambdaType) {
im.LambdaType l = v.type;
if (l.params.length != astn.params.length) {
throw new CompilerError("${l.params.length} parameters expected, got ${astn.params.length}");
}
int i = 0;
l.params.forEach((String p) {
cnode.context.localSymbols.add(new im.CtxSymbol(
baseWindow, resolveVar(astn.params[i], w), p));
i++;
});
var x = tempCtxSave();
Map<ast.TempReference, ast.TempReference> remap = {};
resolve.regenTemps(astn, remap);
compile((v.type as im.LambdaType).code, cnode, baseWindow);
var out = cnode.ret;
tempMap = x;
tempMap.putIfAbsent(astn.ref, () => []).add(out);
} else {
im.BuiltinType l = v.type;
List<im.Var> params = [];
astn.params.forEach((p) => params.add(resolveVar(p, w)));
var out = l.builtin(params, cnode);
tempMap.putIfAbsent(astn.ref, () => []).add(out);
}
} else if (astn is ast.While) {
var cnode = new im.Loop(node, resolveVar(astn.val, window), []);
node.children.add(cnode);
compile(astn.block, cnode);
} else if (astn is ast.NamedReference) {
var cnode = new im.Block(node, [])
..setRet = resolveVar(astn, window);
node.children.add(cnode);
} else {
print("Unused ${astn.runtimeType}");
}
}
compile(rootAST, root, new im.Window(root.context));
return root;
}
\ No newline at end of file
import 'main.dart';
import 'dart:math';
import 'ast.dart' as ast;
import 'package:quiver/iterables.dart' as quiver;
class CtxSymbol {
CtxSymbol(this.window, this.ref, this.name) {
window.context.localSymbols.add(this);
}
final Window window;
final Var ref;
final String name;
}
class Context {
Context([this.parent]) {
if (this.parent == null) {
symbols = localSymbols;
} else {
symbols = quiver.concat([parent.symbols, localSymbols]);
}
}
List<CtxSymbol> localSymbols = [];
Iterable<CtxSymbol> symbols;
void reIndex() {
for (int i = 0; i < windows.length; i++) {
windows[i].id = i;
}
}
List<Window> windows = [];
final Window parent;
}
class Window {
Window(this.context) {
context.windows.add(this);
id = context.windows.indexOf(this);
symbols = context.symbols.where((CtxSymbol s) => id >= s.window.id);
}
Window.before(Window before) {
context = before.context;
before.context.windows.insert(before.id, this);
context.reIndex();
symbols = context.symbols.where((CtxSymbol s) => id >= s.window.id);
}
Window.after(Window after) {
context = after.context;
after.context.windows.insert(after.id + 1, this);
context.reIndex();
symbols = context.symbols.where((CtxSymbol s) => id >= s.window.id);
}
int id;
Context context;
Iterable<CtxSymbol> symbols;
CtxSymbol getSymbol(String name) => symbols.lastWhere((CtxSymbol s) => s.name == name);
bool symbolExists(String name) => symbols.any((CtxSymbol s) => s.name == name);
CtxSymbol requireSymbol(String name) {
if (!symbolExists(name)) throw new CompilerError("No such symbol '$name'");
CtxSymbol s = getSymbol(name);
return s;
}
}
typedef BaseType Resolver(Window);
class BaseType {
String toString() => "null";
bool isDynamic = false;
String get lseek => "ERROR";
String get rseek => "ERROR";
}
class CopyType extends BaseType {
String toString() => "unresolved";
}
class TypeType extends BaseType {
TypeType(this.type);
BaseType type;
String toString() => "typedef $type";