Skip to content

Commit 9d229a9

Browse files
committed
Added support for parsing strings with escaped characters in bootstrap.
Also added initial rationale for exception handling in g3docs/design_decisions.md. This is preliminary, and feedback and edites are welcome. Note that unit tests can now test for expected thrown exceptions. Also check out how nice the error reporting is in bootstrap/parsegen/lexer.stdout.
1 parent a65582a commit 9d229a9

29 files changed

+543
-198
lines changed

bind/bindexpr.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1950,7 +1950,7 @@ static void postProcessBoundStatement(deBlock scopeBlock, deBinding binding) {
19501950
updateSignatureReturnType(deBindingGetSignature(binding), datatype);
19511951
} else if (type == DE_STATEMENT_TYPESWITCH) {
19521952
selectMatchingCase(scopeBlock, binding);
1953-
} else if (type == DE_STATEMENT_PRINT || type == DE_STATEMENT_THROW) {
1953+
} else if (type == DE_STATEMENT_PRINT || type == DE_STATEMENT_THROW || type == DE_STATEMENT_PANIC) {
19541954
dePostProcessPrintStatement(statement);
19551955
} else if (type == DE_STATEMENT_IF) {
19561956
deExpression expression = deStatementGetExpression(statement);

bootstrap/database/block.rn

+12-12
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ use sym
1717
use root
1818
use filepath
1919
use function
20-
use line
20+
use location
2121
use statement
2222

2323
// A liternal block statement. All statements exist within a block.
24-
class Block(self, line: Line) {
25-
self.line = line
24+
class Block(self, location: Location) {
25+
self.location = location
2626
// For dead code analysis.
2727
self.canReturn = false
2828
self.canContinue = false
@@ -82,7 +82,7 @@ class Block(self, line: Line) {
8282

8383
// Make a copy of the block, without sub-blocks.
8484
func copy(self) -> Block {
85-
newBlock = Block(self.line)
85+
newBlock = Block(self.location)
8686
for statement in self.statements() {
8787
statement.appendCopy(newBlock)
8888
}
@@ -106,27 +106,27 @@ unittest {
106106
use expr
107107

108108
mainFunc = getMainFunc()
109-
rootLine = mainFunc.line!
110-
rootFilepath = rootLine.filepath!
109+
rootLocation = mainFunc.location!
110+
rootFilepath = rootLocation.filepath!
111111

112112
func createEmptyBlock() -> Block {
113-
line = Line(rootFilepath, "Create empty block", 0u32)
114-
return Block(line)
113+
location = Location(rootFilepath, 0u32, 0u32, 0u32)
114+
return Block(location)
115115
}
116116

117117
func createPrintlnBlock(text: string) -> Block {
118118
block = createEmptyBlock()
119-
line = Line(rootFilepath, "println \"" + text + "\"", 1u32)
120-
statement = Statement(block, StateType.Println, line)
119+
location = Location(rootFilepath, 0u32, 0u32, 0u32)
120+
statement = Statement(block, StateType.Println, location)
121121
constString = Value(text)
122-
expr = Expr.newConstant(constString, line)
122+
expr = Expr.newConstant(constString, location)
123123
statement.insertExpr(expr)
124124
return block
125125
}
126126

127127
func createPrintlnFunction(owningFunc: Function?, name: string, text: string) -> Function {
128128
block = createPrintlnBlock(text)
129-
function = Function(owningFunction, FuncType.Plain, Sym.new(name), Linkage.Module, rootLine)
129+
function = Function(owningFunction, FuncType.Plain, Sym.new(name), Linkage.Module, rootLocation)
130130
function.insertSubBlock(block)
131131
return function
132132
}

bootstrap/database/expr.rn

+23-23
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
use sym
1616

1717
use filepath
18-
use line
18+
use location
1919
use value
2020
use bigint
2121
use datatype
@@ -184,9 +184,9 @@ func getExprTypeName(type: ExprType) -> string {
184184
}
185185

186186
// The expression class represents all expression trees in Rune.
187-
class Expr(self, type: ExprType, line: Line) {
187+
class Expr(self, type: ExprType, location: Location) {
188188
self.type = type
189-
self.line = line
189+
self.location = location
190190
self.isType = false
191191
self.isConst = false
192192
self.autocast = false // Set on integer constants without a type suffix.
@@ -195,27 +195,27 @@ class Expr(self, type: ExprType, line: Line) {
195195
// self.datatype = null(Datatype)
196196
self.val = null(Value(0u32))
197197

198-
func newConstant(value: Value, line: Line) -> Expr {
199-
expr = Expr(ExprType.Constant, line)
198+
func newConstant(value: Value, location: Location) -> Expr {
199+
expr = Expr(ExprType.Constant, location)
200200
expr.val = value
201201
return expr
202202
}
203203

204-
func newBinary(type: ExprType, left: Expr, right: Expr, line: Line) -> Expr {
205-
expr = Expr(type, line)
204+
func newBinary(type: ExprType, left: Expr, right: Expr, location: Location) -> Expr {
205+
expr = Expr(type, location)
206206
expr.appendChildExpr(left)
207207
expr.appendChildExpr(right)
208208
return expr
209209
}
210210

211-
func newUnary(type: ExprType, child: Expr, line: Line) -> Expr {
212-
expr = Expr(type, line)
211+
func newUnary(type: ExprType, child: Expr, location: Location) -> Expr {
212+
expr = Expr(type, location)
213213
expr.appendChildExpr(child)
214214
return expr
215215
}
216216

217-
func newIdent(sym: Sym, line: Line) -> Expr {
218-
expr = Expr(ExprType.Ident, line)
217+
func newIdent(sym: Sym, location: Location) -> Expr {
218+
expr = Expr(ExprType.Ident, location)
219219
expr.val = Value(sym)
220220
return expr
221221
}
@@ -513,7 +513,7 @@ class Expr(self, type: ExprType, line: Line) {
513513

514514
// Make a deep copy of the expression.
515515
func copy(self: Expr) -> Expr {
516-
newExpr = Expr(self.type, self.line)
516+
newExpr = Expr(self.type, self.location)
517517
// TODO: Comment in when we port datatype to Rune.
518518
// newExpr.datatype = expr.datatype
519519
newExpr.isType = self.isType
@@ -539,14 +539,14 @@ relation OneToOne Function:"Type" Expr:"Type" cascade
539539

540540
unittest {
541541
filepath = Filepath.new("test_filepath", null(Filepath), false)
542-
line = Line(filepath, "Not a real line", 1u32)
542+
location = Location(filepath, 0u32, 0u32, 0u32)
543543

544544
func createBinaryExpr() -> Expr {
545-
left = Expr.newConstant(Value("Hello"), line)
545+
left = Expr.newConstant(Value("Hello"), location)
546546
assert left.getPrecedence() == getPrecedence(ExprType.Constant)
547-
right = Expr.newConstant(Value("World"), line)
547+
right = Expr.newConstant(Value("World"), location)
548548
assert right.getPrecedence() == getPrecedence(ExprType.Constant)
549-
return Expr.newBinary(ExprType.Lt, left, right, line)
549+
return Expr.newBinary(ExprType.Lt, left, right, location)
550550
}
551551
}
552552

@@ -559,11 +559,11 @@ unittest destroyTest {
559559
use block
560560

561561
filepath = Filepath.new("test_filepath", null(Filepath), false)
562-
line = Line(filepath, "Not a real line", 1u32)
563-
block = Block(line)
564-
statement = Statement(block, StateType.Print, line)
562+
location = Location(filepath, 0u32, 0u32, 0u32)
563+
block = Block(location)
564+
statement = Statement(block, StateType.Print, location)
565565
i = Bigint(0xdeadbeefu32, 256u32)
566-
expr = Expr.newConstant(Value(i), line)
566+
expr = Expr.newConstant(Value(i), location)
567567
statement.insertExpr(expr)
568568
expr.destroy()
569569
assert isnull(statement.expr)
@@ -578,13 +578,13 @@ unittest copyTest {
578578
}
579579

580580
unittest unaryTest {
581-
valueExpr = Expr.newConstant(Value(123u32), line)
582-
expr = Expr.newUnary(ExprType.Negate, valueExpr, line)
581+
valueExpr = Expr.newConstant(Value(123u32), location)
582+
expr = Expr.newUnary(ExprType.Negate, valueExpr, location)
583583
expr.dump()
584584
}
585585

586586
unittest newIdentTest {
587-
expr = Expr.newIdent(Sym.new("test"), line)
587+
expr = Expr.newIdent(Sym.new("test"), location)
588588
expr.dump()
589589
}
590590

bootstrap/database/function.rn

+37-39
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
use sym
1616

1717
use root
18-
use line
18+
use location
1919
use filepath
2020
use value
2121
use expr
@@ -70,17 +70,17 @@ func getFuncTypeName(type: FuncType) -> string {
7070

7171
// Create a new function.
7272
class Function(self, parent: Function?, type: FuncType, sym: Sym,
73-
linkage: Linkage, line: Line) {
73+
linkage: Linkage, location: Location) {
7474
self.type = type
7575
self.sym = sym
7676
self.linkage = linkage
77-
self.line = line
77+
self.location = location
7878
self.isExtern = linkage == Linkage.ExternC || linkage == Linkage.ExternRpc
7979
if !isnull(parent) {
8080
parent!.appendChildFunction(self)
81-
Ident(parent!, self, sym, line)
81+
Ident(parent!, self, sym, location)
8282
}
83-
subBlock = Block(line)
83+
subBlock = Block(location)
8484
// Assume it can return until we learn otherwise. This is only an issue when
8585
// evaluating recursive functions.
8686
subBlock.canReturn = true
@@ -142,7 +142,7 @@ class Function(self, parent: Function?, type: FuncType, sym: Sym,
142142

143143
// Make a copy of the function in |destBlock|.
144144
func copy(self, destFunc: Function) -> Function {
145-
newFunction = Function(destFunc, self.type, self.sym, self.linkage, self.line)
145+
newFunction = Function(destFunc, self.type, self.sym, self.linkage, self.location)
146146
for variable in self.variables() {
147147
variable.copy(newFunction)
148148
}
@@ -174,28 +174,27 @@ class Function(self, parent: Function?, type: FuncType, sym: Sym,
174174
func appendFunctionCall(self, childFunction: Function) -> Statement {
175175
ident = childFunction.firstNameIdent
176176
pathExpr = ident!.createPathExpr()
177-
text = "%s()\n" % childFunction.name()
178177
block = self.subBlock!
179-
line = Line(block.line.filepath!, text, 0u32)
180-
emptyParamsExpr = Expr(ExprType.List, line)
181-
callExpr = Expr.newBinary(ExprType.Call, pathExpr, emptyParamsExpr, line)
182-
statement = Statement(block, StateType.Call, line)
178+
location = Location(block.location.filepath!, 0u32, 0u32, 0u32)
179+
emptyParamsExpr = Expr(ExprType.List, location)
180+
callExpr = Expr.newBinary(ExprType.Call, pathExpr, emptyParamsExpr, location)
181+
statement = Statement(block, StateType.Call, location)
183182
statement.insertExpr(callExpr)
184183
return statement
185184
}
186185

187186
// Declare an iterator.
188187
func newIterator(owningFunc: Function, name: Sym, selfName: Sym, linkage: Linkage,
189-
line: Line) -> Function {
190-
iteratorFunc = Function(owningFunc, FuncType.Iterator, name, linkage, line)
191-
Variable(iteratorFunc, true, false, selfName, null(Expr), null(Expr), false, line)
188+
location: Location) -> Function {
189+
iteratorFunc = Function(owningFunc, FuncType.Iterator, name, linkage, location)
190+
Variable(iteratorFunc, true, false, selfName, null(Expr), null(Expr), false, location)
192191
return iteratorFunc
193192
}
194193

195194
// Create an overloaded operator.
196-
func newOperator(owningFunc: Function, opType: ExprType, line: Line) -> Function {
195+
func newOperator(owningFunc: Function, opType: ExprType, location: Location) -> Function {
197196
name = owningFunc.createUniqueSym(Sym.new(getExprTypeName(opType)))
198-
function = Function(owningFunc, FuncType.Operator, name, Linkage.Package, line)
197+
function = Function(owningFunc, FuncType.Operator, name, Linkage.Package, location)
199198
root = getRoot()
200199
return function
201200
}
@@ -217,27 +216,26 @@ class Function(self, parent: Function?, type: FuncType, sym: Sym,
217216

218217
// Create a path expression to this function.
219218
func createPathExpr(self) -> Expr {
220-
identExpr = Expr.newIdent(self.sym, self.line)
219+
identExpr = Expr.newIdent(self.sym, self.location)
221220
parent = self.parentFunction
222221
if isnull(parent) {
223222
return identExpr
224223
}
225224
prefixExpr = parent!.createPathExpr()
226-
return Expr.newBinary(ExprType.Dot, prefixExpr, identExpr, self.line)
225+
return Expr.newBinary(ExprType.Dot, prefixExpr, identExpr, self.location)
227226
}
228227
}
229228

230229
// Append a call statement to the module initialization function in the root function.
231230
func insertModuleInitializationCall(moduleFunc: Function) {
232231
pathExpr = moduleFunc.createPathExpr()
233232
block = moduleFunc.subBlock!
234-
text = "%s()\n" % moduleFunc.name()
235-
line = Line(block.line.filepath!, text, 0u32)
236-
emptyParamsExpr = Expr(ExprType.List, line)
237-
callExpression = Expr.newBinary(ExprType.Call, pathExpr, emptyParamsExpr, line)
233+
location = Location(block.location.filepath!, 0u32, 0u32, 0u32)
234+
emptyParamsExpr = Expr(ExprType.List, location)
235+
callExpression = Expr.newBinary(ExprType.Call, pathExpr, emptyParamsExpr, location)
238236
root = getRoot()
239237
block = getMainFunc().subBlock!
240-
statement = Statement(block, StateType.Call, line)
238+
statement = Statement(block, StateType.Call, location)
241239
statement.insertExpr(callExpression)
242240
// Move the statement to after the last initialization call.
243241
lastInitializer = root.lastInitializerStatement
@@ -258,24 +256,24 @@ relation OneToOne Filepath:"Module" Function:"Module"
258256
// Create the main function.
259257
func createMainFunc() {
260258
rootFilepath = Filepath("Root filepath", null(Filepath), true)
261-
rootLine = Line(rootFilepath, "Create main", 0u32)
259+
rootLocation = Location(rootFilepath, 0u32, 0u32, 0u32)
262260
mainFunc = Function(null(Function), FuncType.Package,
263-
Sym.new("main"), Linkage.Package, rootLine)
264-
typeExpr = Expr(ExprType.IntType, rootLine)
261+
Sym.new("main"), Linkage.Package, rootLocation)
262+
typeExpr = Expr(ExprType.IntType, rootLocation)
265263
typeExpr.width = 32u32
266264
mainFunc.insertTypeExpr(typeExpr)
267265
getRoot().insertMainFunction(mainFunc)
268266
rootBlock = mainFunc.subBlock!
269267
rootFilepath.insertModuleFunction(mainFunc)
270-
nullExpr = null(Expr(ExprType.Add, rootLine))
271-
u32TypeExpr = Expr(ExprType.UintType, rootLine)
272-
stringTypeExpr = Expr(ExprType.StringType, rootLine)
268+
nullExpr = null(Expr(ExprType.Add, rootLocation))
269+
u32TypeExpr = Expr(ExprType.UintType, rootLocation)
270+
stringTypeExpr = Expr(ExprType.StringType, rootLocation)
273271
u32TypeExpr.width = 32u32
274-
argcVar = Variable(mainFunc, true, true, Sym.new("argc"), nullExpr, u32TypeExpr, true, rootLine)
272+
argcVar = Variable(mainFunc, true, true, Sym.new("argc"), nullExpr, u32TypeExpr, true, rootLocation)
275273
argvVar = Variable(mainFunc, true, true, Sym.new("argv"), nullExpr,
276-
stringTypeExpr, true, rootLine)
277-
statement = Statement(mainFunc.subBlock!, StateType.Return, rootLine)
278-
retVal = Expr.newConstant(Value(0i32), rootLine)
274+
stringTypeExpr, true, rootLocation)
275+
statement = Statement(mainFunc.subBlock!, StateType.Return, rootLocation)
276+
retVal = Expr.newConstant(Value(0i32), rootLocation)
279277
statement.insertExpr(retVal)
280278
}
281279

@@ -285,19 +283,19 @@ unittest {
285283
use statement
286284

287285
mainFunc = getMainFunc()
288-
rootLine = mainFunc.line
289-
rootFilepath = rootLine.filepath
286+
rootLocation = mainFunc.location
287+
rootFilepath = rootLocation.filepath
290288
argcVar = mainFunc.firstVariable!
291289
argvVar = argcVar.nextFunctionVariable!
292290

293291
func createEmptyFunction(owningFunc: Function?, name: string) -> Function {
294-
return Function(owningFunc, FuncType.Plain, Sym.new(name), Linkage.Module, rootLine)
292+
return Function(owningFunc, FuncType.Plain, Sym.new(name), Linkage.Module, rootLocation)
295293
}
296294

297295
func createPrintlnFunction(owningFunc: Function?, name: string, text: string) {
298296
function = createEmptyFunction(owningFunc, name);
299297
block = function.subBlock!
300-
Statement(block, StateType.Println, rootLine)
298+
Statement(block, StateType.Println, rootLocation)
301299
return function
302300
}
303301
}
@@ -328,8 +326,8 @@ unittest prependAndAppendFunctionCallTest {
328326

329327
unittest newIteratorAndOperatorTest {
330328
itr = Function.newIterator(mainFunc, Sym.new("testItr"), Sym.new("self"),
331-
Linkage.Module, rootLine)
332-
op = Function.newOperator(mainFunc, ExprType.Add, rootLine)
329+
Linkage.Module, rootLocation)
330+
op = Function.newOperator(mainFunc, ExprType.Add, rootLocation)
333331
itr.dump()
334332
op.dump()
335333
itr.destroy()

0 commit comments

Comments
 (0)