diff --git a/Makefile b/Makefile index ffcb0c0..6edcbd8 100644 --- a/Makefile +++ b/Makefile @@ -134,6 +134,7 @@ test/example: ${CELL} -d -t riscv tests/examples/string.cell && ckb-debugger --bin string | grep "eq" ${CELL} -d -t riscv tests/examples/strings.cell && ckb-debugger --bin strings | grep "aa-bb" ${CELL} -d -t riscv tests/examples/make-slice.cell && ckb-debugger --bin make-slice | grep "0422" + ${CELL} -d -t riscv tests/examples/panic.cell && ckb-debugger --bin panic | grep "runtime panic: hah" ${CELL} -d -t riscv tests/examples/func.cell && ckb-debugger --bin func | grep "999" ${CELL} -t riscv tests/examples/cell-data.cell && ckb-debugger --bin cell-data ${CELL} -t riscv tests/examples/inputs.cell && ckb-debugger --bin inputs diff --git a/compiler/compiler/func.go b/compiler/compiler/func.go index 81bbe3d..00955db 100644 --- a/compiler/compiler/func.go +++ b/compiler/compiler/func.go @@ -397,6 +397,10 @@ func (c *Compiler) compileCallNode(v *parser.CallNode) value.Value { return c.appendFuncCall(v) case "print": return c.printFuncCall(v) + case "panic": + message, _ := v.Arguments[0].(*parser.ConstantNode) + c.panic(c.contextBlock, message.ValueStr) + return value.Value{} } } diff --git a/compiler/lexer/keywords.go b/compiler/lexer/keywords.go index 12a18a1..570e4c5 100644 --- a/compiler/lexer/keywords.go +++ b/compiler/lexer/keywords.go @@ -21,4 +21,5 @@ var keywords = map[string]struct{}{ "interface": {}, "range": {}, "make": {}, + "panic": {}, } diff --git a/compiler/parser/parser.go b/compiler/parser/parser.go index 8eb92db..c111e01 100644 --- a/compiler/parser/parser.go +++ b/compiler/parser/parser.go @@ -335,6 +335,24 @@ func (p *parser) parseOneWithOptions(withAheadParse, withArithAhead, withIdentif return outerConditionNode } + if current.Val == "panic" { + p.i++ + lParent := p.lookAhead(0) + p.expect(lParent, lexer.Item{Type: lexer.OPERATOR, Val: "("}) + p.i++ + args := p.parseUntil(lexer.Item{Type: lexer.OPERATOR, Val: ")"}) + if len(args) != 1 { + panic("wrong number of arguments for panic(message)") + } + if _, ok := args[0].(*ConstantNode); !ok { + panic("wrong type of argument for panic(message)") + } + return &CallNode{ + Function: &NameNode{Name: "panic"}, + Arguments: args, + } + } + // "make" is a construtor command for composed types if current.Val == "make" { p.i++ diff --git a/tests/examples/panic.cell b/tests/examples/panic.cell new file mode 100644 index 0000000..416f659 --- /dev/null +++ b/tests/examples/panic.cell @@ -0,0 +1,6 @@ +package main + +func main() { + panic("hah") + return 0 +} \ No newline at end of file