Skip to content

Commit

Permalink
Merge branch 'channels'
Browse files Browse the repository at this point in the history
  • Loading branch information
arnav-ag committed Apr 12, 2024
2 parents 43ff1ba + e00a205 commit 7ef08a6
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 176 deletions.
96 changes: 12 additions & 84 deletions src/parser/ooga.js
Original file line number Diff line number Diff line change
Expand Up @@ -6254,7 +6254,7 @@ function peg$parse(input, options) {
}

function peg$parseForWithInitTestUpdate() {
var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16;
var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12;

s0 = peg$currPos;
s1 = peg$parseForToken();
Expand Down Expand Up @@ -6285,35 +6285,11 @@ function peg$parse(input, options) {
s9 = peg$parseExpression();
if (s9 !== peg$FAILED) {
s10 = peg$parse__();
if (input.charCodeAt(peg$currPos) === 123) {
s11 = peg$c75;
peg$currPos++;
} else {
s11 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$e96); }
}
s11 = peg$parseBlockStatement();
if (s11 !== peg$FAILED) {
s12 = peg$parse__();
s13 = peg$parseSequenceStatement();
if (s13 === peg$FAILED) {
s13 = null;
}
s14 = peg$parse__();
if (input.charCodeAt(peg$currPos) === 125) {
s15 = peg$c43;
peg$currPos++;
} else {
s15 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$e60); }
}
if (s15 !== peg$FAILED) {
s16 = peg$parse__();
peg$savedPos = s0;
s0 = peg$f76(s3, s6, s9, s13);
} else {
peg$currPos = s0;
s0 = peg$FAILED;
}
peg$savedPos = s0;
s0 = peg$f76(s3, s6, s9, s11);
} else {
peg$currPos = s0;
s0 = peg$FAILED;
Expand Down Expand Up @@ -6347,7 +6323,7 @@ function peg$parse(input, options) {
}

function peg$parseForWithTest() {
var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10;
var s0, s1, s2, s3, s4, s5, s6;

s0 = peg$currPos;
s1 = peg$parseForToken();
Expand All @@ -6356,35 +6332,11 @@ function peg$parse(input, options) {
s3 = peg$parseForTest();
if (s3 !== peg$FAILED) {
s4 = peg$parse__();
if (input.charCodeAt(peg$currPos) === 123) {
s5 = peg$c75;
peg$currPos++;
} else {
s5 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$e96); }
}
s5 = peg$parseBlockStatement();
if (s5 !== peg$FAILED) {
s6 = peg$parse__();
s7 = peg$parseSequenceStatement();
if (s7 === peg$FAILED) {
s7 = null;
}
s8 = peg$parse__();
if (input.charCodeAt(peg$currPos) === 125) {
s9 = peg$c43;
peg$currPos++;
} else {
s9 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$e60); }
}
if (s9 !== peg$FAILED) {
s10 = peg$parse__();
peg$savedPos = s0;
s0 = peg$f77(s3, s7);
} else {
peg$currPos = s0;
s0 = peg$FAILED;
}
peg$savedPos = s0;
s0 = peg$f77(s3, s5);
} else {
peg$currPos = s0;
s0 = peg$FAILED;
Expand All @@ -6402,41 +6354,17 @@ function peg$parse(input, options) {
}

function peg$parseForInfinite() {
var s0, s1, s2, s3, s4, s5, s6, s7, s8;
var s0, s1, s2, s3, s4;

s0 = peg$currPos;
s1 = peg$parseForToken();
if (s1 !== peg$FAILED) {
s2 = peg$parse__();
if (input.charCodeAt(peg$currPos) === 123) {
s3 = peg$c75;
peg$currPos++;
} else {
s3 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$e96); }
}
s3 = peg$parseBlockStatement();
if (s3 !== peg$FAILED) {
s4 = peg$parse__();
s5 = peg$parseSequenceStatement();
if (s5 === peg$FAILED) {
s5 = null;
}
s6 = peg$parse__();
if (input.charCodeAt(peg$currPos) === 125) {
s7 = peg$c43;
peg$currPos++;
} else {
s7 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$e60); }
}
if (s7 !== peg$FAILED) {
s8 = peg$parse__();
peg$savedPos = s0;
s0 = peg$f78(s5);
} else {
peg$currPos = s0;
s0 = peg$FAILED;
}
peg$savedPos = s0;
s0 = peg$f78(s3);
} else {
peg$currPos = s0;
s0 = peg$FAILED;
Expand Down
6 changes: 3 additions & 3 deletions src/parser/ooga.pegjs
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,7 @@ ForWithInitTestUpdate
init:ForInitStatement ";" __
test:ForTest ";" __
update:Expression __
"{" __ body: StatementList? __ "}" __
body:BlockStatement __
{
return {
tag: "ForStatement",
Expand All @@ -769,7 +769,7 @@ ForWithInitTestUpdate
ForWithTest
= ForToken __
test:ForTest __
"{" __ body: StatementList? __ "}" __
body:BlockStatement __
{
return {
tag: "ForStatement",
Expand All @@ -784,7 +784,7 @@ ForWithTest

ForInfinite
= ForToken __
"{" __ body: StatementList? __ "}" __
body:BlockStatement __
{
return {
tag: "ForStatement",
Expand Down
88 changes: 55 additions & 33 deletions src/tests/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1076,7 +1076,7 @@ func booga(x []int) int {
var sum int = 0;
for var i int = 0; i < n; i++ {
sum = sum + x[i];
}
}
return sum;
}
Expand Down Expand Up @@ -1114,9 +1114,9 @@ func googaDaBooga() []int {
func addOne(x []int) []int {
for i := 0; i < len(x); i++ {
x[i] = x[i] + 1;
}
}
return x;
}
}
var x = googaDaBooga();
Expand All @@ -1131,9 +1131,9 @@ x[0];
defaultNumWords
);


// Test unbuffered goroutines
testProgram(`
testProgram(
`
func fooga(x chan int) {
// writes to x, should block
print(0);
Expand All @@ -1155,12 +1155,15 @@ for i := 0; i < 10; i++ {
// do nothing to stall to see 'fooga' being printed
}
10;
`, 10,
`,
10,
'0\n"booga"\n1\n"fooga"',
defaultNumWords);
defaultNumWords
);

// Test unblocking buffered goroutine
testProgram(`
testProgram(
`
func fooga(x chan int) {
// writes to x, should be unblocking
print(0);
Expand All @@ -1182,15 +1185,17 @@ for i := 0; i < 10; i++ {
// do nothing to stall to see 'fooga' being printed
}
10;
`, 10,
`,
10,
'0\n"fooga"\n"booga"\n1',
defaultNumWords);

defaultNumWords
);

// Test blocking buffered goroutine
testProgram(`
testProgram(
`
func foo(x chan int) {
print(0);
print(0);
x <- 1; // unblocking write
print("foo"); // should print immediately after 0
}
Expand All @@ -1204,7 +1209,7 @@ func goo(x chan int) {
func hoo(x chan int) {
print(3);
var y int = <-x; // shud be an unblocking read
print(y); // verify that y is equal to 1
print(y); // verify that y is equal to 1
}
var x chan int = make(chan int, 1); // buffered channel of size 1
Expand All @@ -1216,22 +1221,25 @@ for i := 0; i < 10; i++ {
// do nothing to stall to see everything being printed
}
10;
`, 10,
`,
10,
'0\n"foo"\n2\n3\n1\n"goo"',
defaultNumWords);
defaultNumWords
);

// test pushing strings onto channels
testProgram(`
testProgram(
`
func foo(x chan string) {
print("before foo");
print("before foo");
x<- "Jotham"; // non blocking write
print("after foo");
print("after foo");
}
func goo(x chan string) {
print("before goo");
print("before goo");
x<- "Wong"; // non blocking write
print("after goo");
print("after goo");
}
func hoo(x chan string) {
Expand All @@ -1254,13 +1262,15 @@ for i := 0; i < 100; i++ {
// do nothing to stall to see everything being printed
}
10;
`, 10,
'"before foo"\n"after foo"\n"before goo"\n"after goo"\n"before hoo"\n"Jotham Wong"\n"after hoo"'
, defaultNumWords);

`,
10,
'"before foo"\n"after foo"\n"before goo"\n"after goo"\n"before hoo"\n"Jotham Wong"\n"after hoo"',
defaultNumWords
);

// test that main will expire before blocking progresses
testProgram(`
testProgram(
`
func foo(x chan int) {
var y = <-x; // blocking since no actual value in x yet
print("This will not show");
Expand All @@ -1276,23 +1286,35 @@ go foo(x);
go goo(x);
print("This is the end");
10; // do not give time for foo to read
`, 10,
'"This will show"\n"This is the end"', defaultNumWords);
`,
10,
'"This will show"\n"This is the end"',
defaultNumWords
);

// Simple test for deadlock detection
testProgram(`
testProgram(
`
func foo(x chan int) {
x <- 5;
}
var x chan int = make(chan int); // unbuffered channel
go foo(x);
x <- 6; // will deadlock here
`, 'Deadlock detected!', '', defaultNumWords);

`,
'Deadlock detected!',
'',
defaultNumWords
);

// Simple test for doomed forever
testProgram(`
testProgram(
`
var x chan int = make(chan int); // unbuffered channel
<-x; // will block forever
`, 'Stuck forever!', '', defaultNumWords);
`,
'Stuck forever!',
'',
defaultNumWords
);
9 changes: 6 additions & 3 deletions src/vm/oogavm-compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,9 @@ const compileComp = {
goto_instr.addr = wc;
},
BlockStatement: (comp, ce) => {
if (!comp.body) {
return;
}
const declarations: CompileTimeVariable[] = scanForLocalsBlock(comp.body);
// Only enter and exit scope if there are actually declarations.
if (declarations.length == 0) {
Expand Down Expand Up @@ -779,8 +782,8 @@ const compileComp = {
instrs[wc++] = { tag: Opcodes.LDARRI };
},
MakeCallExpression: (comp, ce) => {
console.log('Compiling MakeCallExpression');
console.log(comp);
log('Compiling MakeCallExpression');
log(comp);
if (is_type(comp.type, ChanType) && comp.args.length === 0) {
// unbuffered channel
instrs[wc++] = { tag: Opcodes.CREATE_UNBUFFERED };
Expand All @@ -793,7 +796,7 @@ const compileComp = {
// Slice (currently not supporting dynamically resizable array)
// so this is just a default initialized array at the moment, that means
} else {
throw new OogaError( 'Unsupported make type at the moment!');
throw new OogaError('Unsupported make type at the moment!');
}
},
ChannelReadExpression: (comp, ce) => {
Expand Down
4 changes: 2 additions & 2 deletions src/vm/oogavm-heap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -716,7 +716,7 @@ export function pushUnbufferedChannel(address: number, value: number) {
export function popUnbufferedChannel(address: number): number {
// check that unbuffered channel is not empty!
const size = getUnBufferChannelLength(address);
log("Size of unbuffered channel at addr " + address + " is " + size);
log('Size of unbuffered channel at addr ' + address + ' is ' + size);
if (size !== 1) {
throw new OogaError('Attempting to pop empty unbuffered channel in the heap. Bug!');
}
Expand Down Expand Up @@ -806,7 +806,7 @@ export function debugHeap(): void {
break;
case Tag.UNBUFFERED:
if (getUnBufferChannelLength(curr) === 0) {
log("Empty unbuffered channel");
log('Empty unbuffered channel');
} else {
log('Unbuffered value: ' + getWord(curr + headerSize + 1));
}
Expand Down
Loading

0 comments on commit 7ef08a6

Please sign in to comment.