Skip to content

Commit 6cab59a

Browse files
authored
Merge pull request #28 from callisto-lang/SafeStack
add unsafe block
2 parents 5e47c06 + 0ea795c commit 6cab59a

File tree

3 files changed

+76
-1
lines changed

3 files changed

+76
-1
lines changed

source/compiler.d

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,11 @@ class Compiler {
483483
case NodeType.Implement: backend.CompileImplement(cast(ImplementNode) inode); break;
484484
case NodeType.Set: backend.CompileSet(cast(SetNode) inode); break;
485485
case NodeType.TryCatch: backend.CompileTryCatch(cast(TryCatchNode) inode); break;
486+
case NodeType.Unsafe: {
487+
auto node = cast(UnsafeNode) inode;
488+
Compile(node.nodes);
489+
break;
490+
}
486491
default: {
487492
backend.Error(inode.error, "Unimplemented node '%s'", inode.type);
488493
}

source/parser.d

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ enum NodeType {
3333
Addr,
3434
Implement,
3535
Set,
36-
TryCatch
36+
TryCatch,
37+
Unsafe
3738
}
3839

3940
class Node {
@@ -521,6 +522,27 @@ class TryCatchNode : Node {
521522
}
522523
}
523524

525+
class UnsafeNode : Node {
526+
string[] paramTypes;
527+
string[] retTypes;
528+
Node[] nodes;
529+
530+
this(ErrorInfo perror) {
531+
type = NodeType.Unsafe;
532+
error = perror;
533+
}
534+
535+
override string toString() {
536+
string ret = format("unsafe %d -> %d", paramTypes.length, retTypes.length);
537+
538+
foreach (ref node ; nodes) {
539+
ret ~= node.toString() ~ '\n';
540+
}
541+
542+
return ret ~ "end";
543+
}
544+
}
545+
524546
class ParserError : Exception {
525547
this() {
526548
super("", "", 0);
@@ -1228,6 +1250,47 @@ class Parser {
12281250
return ret;
12291251
}
12301252

1253+
Node ParseUnsafe() {
1254+
auto ret = new UnsafeNode(GetError());
1255+
parsing = NodeType.Unsafe;
1256+
1257+
Next();
1258+
1259+
while (!IsIdentifier("begin") && !IsIdentifier("->")) {
1260+
Expect(TokenType.Identifier);
1261+
ret.paramTypes ~= tokens[i].contents;
1262+
Next();
1263+
Expect(TokenType.Identifier);
1264+
Next();
1265+
}
1266+
1267+
if (IsIdentifier("->")) {
1268+
Next();
1269+
1270+
while (!IsIdentifier("begin")) {
1271+
Expect(TokenType.Identifier);
1272+
ret.retTypes ~= tokens[i].contents; // return type
1273+
1274+
Next();
1275+
Expect(TokenType.Identifier); // return name, ignored
1276+
1277+
if (tokens[i].contents == "begin") {
1278+
Error("Begin in return name");
1279+
}
1280+
Next();
1281+
}
1282+
}
1283+
1284+
Next();
1285+
1286+
while (!IsIdentifier("end")) {
1287+
ret.nodes ~= ParseStatement();
1288+
Next();
1289+
}
1290+
1291+
return ret;
1292+
}
1293+
12311294
Node ParseStatement() {
12321295
switch (tokens[i].type) {
12331296
case TokenType.Integer: {
@@ -1255,6 +1318,7 @@ class Parser {
12551318
case "implement": return ParseImplement();
12561319
case "try": return ParseTryCatch();
12571320
case "->": return ParseSet();
1321+
case "unsafe": return ParseUnsafe();
12581322
default: return new WordNode(GetError(), tokens[i].contents);
12591323
}
12601324
}

source/stackCheck.d

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,11 @@ class StackChecker {
373373
}
374374
}
375375

376+
void EvaluateUnsafe(UnsafeNode node) {
377+
Pop(node, node.paramTypes.length);
378+
Push(node, node.retTypes.length);
379+
}
380+
376381
void EvaluateNode(Node node) {
377382
switch (node.type) {
378383
case NodeType.Word: {
@@ -407,6 +412,7 @@ class StackChecker {
407412
case NodeType.Set: Pop(node, 1); break;
408413
case NodeType.TryCatch: EvaluateTryCatch(cast(TryCatchNode) node); break;
409414
case NodeType.Struct: EvaluateStruct(cast(StructNode) node); break;
415+
case NodeType.Unsafe: EvaluateUnsafe(cast(UnsafeNode) node); break;
410416
default: break;
411417
}
412418
}

0 commit comments

Comments
 (0)