Permalink
Browse files

Work on new scope system.

  • Loading branch information...
neilellis committed Aug 6, 2017
1 parent f1d3402 commit c32f908ed53408f993231784618037686f68f120
View
@@ -110,5 +110,12 @@ docker run -v $HOME/.github:/root/.github -v $HOME/.dollar:/root/.dollar -v $(pw
[![Docker Registry](https://img.shields.io/docker/pulls/sillelien/dollarscript-headless.svg)](https://registry.hub.docker.com/u/sillelien/dollarscript-headless)
## Research & Background Reading
http://www.drdobbs.com/architecture-and-design/so-you-want-to-write-your-own-language/240165488
https://www.youtube.com/watch?v=Sg4U4r_AgJU
$BLURB
Binary file not shown.
@@ -30,7 +30,9 @@ Here is an example of what Dollar looks like
```dollar
def testParams ($2 + " " + $1)
def testParams {$2 + " " + $1}
@@ testParams ("Hello", "World")
.: testParams ("Hello", "World") == "World Hello"
@@ -341,6 +343,51 @@ Dollar (at present) supports numerical and character ranges
```
### Understanding Scopes
Dollar makes extensive use of scope [closure](https://en.wikipedia.org/wiki/Closure_(computer_programming)). Any form of delayed execution has closure over it's parent scope. Let's start with a simple example:
```dollar
var outer=10;
def func {
outer;
}
func() <=> 10;
```
In the above example `func` is a block collection which returns `outer`. It has access to `outer` because at the time of decleration outer is in it's parent scope.
```dollar
def func {
var inner=10;
{$1+inner}
}
func()(10) <=> 20;
```
So all of that looks fairly familiar, but remember anything with delayed execution has scope closure so
```dollar
var outer=10;
1 <=> 2
const scopedArray := [$1,outer,{var inner=20;inner}]
.: scopedArray(5)[0] == 4;
scopedArray(5)[0] <=> 4;
scopedArray(5)[1] <=> 10;
scopedArray(5)[2]() <=> 20;
```
In the above example we now return an anonymous block collection from func which we then paramterize with the value `10`. When `func` is executed it returns the paramterized block, which we then call with `10` and which adds the value `inner` to the parameter (`$1`) - naturally the result is 20.
###Error Handling
Error handling couldn't be simpler. Define an error expression using the error keyword, the expression supplied will be evaluated on an error occurring within any sub scope of the scope in which it is defined. The special variables `msg` and `type` will be assigned values.
@@ -19,7 +19,46 @@
import com.sillelien.dollar.api.DollarException;
import dollar.internal.runtime.script.api.ParserOptions;
import org.jetbrains.annotations.NotNull;
import org.pegdown.ast.*;
import org.pegdown.ast.AbbreviationNode;
import org.pegdown.ast.AnchorLinkNode;
import org.pegdown.ast.AutoLinkNode;
import org.pegdown.ast.BlockQuoteNode;
import org.pegdown.ast.BulletListNode;
import org.pegdown.ast.CodeNode;
import org.pegdown.ast.DefinitionListNode;
import org.pegdown.ast.DefinitionNode;
import org.pegdown.ast.DefinitionTermNode;
import org.pegdown.ast.ExpImageNode;
import org.pegdown.ast.ExpLinkNode;
import org.pegdown.ast.HeaderNode;
import org.pegdown.ast.HtmlBlockNode;
import org.pegdown.ast.InlineHtmlNode;
import org.pegdown.ast.ListItemNode;
import org.pegdown.ast.MailLinkNode;
import org.pegdown.ast.Node;
import org.pegdown.ast.OrderedListNode;
import org.pegdown.ast.ParaNode;
import org.pegdown.ast.QuotedNode;
import org.pegdown.ast.RefImageNode;
import org.pegdown.ast.RefLinkNode;
import org.pegdown.ast.ReferenceNode;
import org.pegdown.ast.RootNode;
import org.pegdown.ast.SimpleNode;
import org.pegdown.ast.SpecialTextNode;
import org.pegdown.ast.StrikeNode;
import org.pegdown.ast.StrongEmphSuperNode;
import org.pegdown.ast.SuperNode;
import org.pegdown.ast.TableBodyNode;
import org.pegdown.ast.TableCaptionNode;
import org.pegdown.ast.TableCellNode;
import org.pegdown.ast.TableColumnNode;
import org.pegdown.ast.TableHeaderNode;
import org.pegdown.ast.TableNode;
import org.pegdown.ast.TableRowNode;
import org.pegdown.ast.TextNode;
import org.pegdown.ast.VerbatimNode;
import org.pegdown.ast.Visitor;
import org.pegdown.ast.WikiLinkNode;
public class CodeExtractionVisitor implements Visitor {
@Override
@@ -198,7 +237,8 @@ public void visit(TableRowNode node) {
public void visit(@NotNull VerbatimNode node) {
if ("dollar".equals(node.getType())) {
try {
new DollarParserImpl(new ParserOptions()).parse(node.getText(), false);
new DollarParserImpl(new ParserOptions()).parse(
new ScriptScope(node.getText(), "(markdown)", true), node.getText());
} catch (Exception e) {
throw new DollarException(e, node.getText());
}
@@ -161,6 +161,7 @@ public var parse(ScriptScope scope, @NotNull String source) throws Exception {
DollarStatic.context().setClassLoader(classLoader);
Parser<?> parser = buildParser(false, scope);
var parse = (var) parser.from(TOKENIZER, DollarLexer.IGNORED).parse(source);
parse._fixDeep(false);
return $(exports);
});
@@ -239,9 +240,9 @@ private var parseMarkdown(File file) throws IOException {
Parser<var> parser = (TERMINATOR_SYMBOL.optional()).next(or(expression, block).followedBy(
TERMINATOR_SYMBOL).many1()).map(v -> {
log.debug("Ended Parse Phase");
var resultVar = $(v);
var resultVar = DollarFactory.blockCollection(v);
log.debug("Starting Runtime Phase");
var fixedResult = resultVar._fix(1, false);
var fixedResult = resultVar._fix(false);
log.debug("Ended Runtime Phase");
return fixedResult;
});
@@ -869,7 +870,7 @@ public var map(var rhs) {
),
array(KEYWORD("export").optional(),
IDENTIFIER.between(OP("<"), OP(">")).optional(), KEYWORD("def"),
IDENTIFIER, ref.lazy(), expression(null, true))
IDENTIFIER, expression(null, true))
)
).token().map(
new DefinitionOperator(true, this)).map(
@@ -453,19 +453,19 @@ public static var setVariable(@NotNull Scope scope,
}
@NotNull
public static var constrain(Scope scope, @NotNull var rhs, var constraint, String source) {
public static var constrain(Scope scope, @NotNull var value, var constraint, String source) {
// System.err.println("(" + source + ") " + rhs.$type().constraint());
if (!Objects.equals(rhs._constraintFingerprint(), source)) {
if (rhs._constraintFingerprint() != null && !rhs._constraintFingerprint().isEmpty()) {
if (!Objects.equals(value._constraintFingerprint(), source)) {
if (value._constraintFingerprint() != null && !value._constraintFingerprint().isEmpty()) {
scope.handleError(new DollarScriptException(
"Trying to assign an invalid constrained variable " + rhs._constraintFingerprint() + " vs " + source,
rhs));
"Trying to assign an invalid constrained variable " + value._constraintFingerprint() + " vs " + source,
value));
}
} else {
if (rhs._constraintFingerprint() != null && !rhs._constraintFingerprint().isEmpty()) {
if (value._constraintFingerprint() != null && !value._constraintFingerprint().isEmpty()) {
// System.err.println("Fingerprint: " + rhs.$type().constraint());
}
}
return rhs._constrain(constraint, source);
return value._constrain(constraint, source);
}
}
View
@@ -87,7 +87,7 @@
<dependency>
<groupId>com.sillelien</groupId>
<artifactId>dollar-core</artifactId>
<version>0.3.357</version>
<version>0.3.361</version>
</dependency>
<dependency>
<groupId>com.sillelien</groupId>

0 comments on commit c32f908

Please sign in to comment.