You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
4.1 KiB
139 lines
4.1 KiB
abstract class TlToken { |
|
static Iterable<TlToken> tokenize(String file) sync* { |
|
var lastWasNone = false; |
|
for (final untrimmedLine in file.split(RegExp(r'[\r\n]'))) { |
|
final line = untrimmedLine.trim(); |
|
if (line.isEmpty) { |
|
if (!lastWasNone) { |
|
yield TlTokenNone(); |
|
lastWasNone = true; |
|
} |
|
continue; |
|
} |
|
else { |
|
lastWasNone = false; |
|
if (line.startsWith('//')) { |
|
// Comment |
|
if (!line.contains('@')) { |
|
yield TlTokenCommentLine(line); |
|
continue; |
|
} |
|
// Skip to first @tag |
|
final interestLine = line.substring(line.indexOf('@')); |
|
for (final unTrimmedTaggedChunk in interestLine.split('@')) { |
|
final taggedChunk = unTrimmedTaggedChunk.trim(); |
|
if (taggedChunk.isEmpty) { |
|
continue; |
|
} |
|
final firstWs = taggedChunk.indexOf(RegExp(r'\s')); |
|
final tagName = taggedChunk.substring(0, firstWs); |
|
final tagValue = taggedChunk.substring(firstWs).trim(); |
|
yield TlTokenCommentTag(name: tagName, value: tagValue); |
|
} |
|
} |
|
else if (line == '---functions---') { |
|
yield TlTokenFunctionsDelimiter(); |
|
} |
|
else { |
|
// class |
|
// Split by space |
|
final chunksIt = line.split(RegExp(r'\s+')).iterator; |
|
// First is name |
|
chunksIt.moveNext(); |
|
final name = chunksIt.current; |
|
// Then there are parameters until = |
|
final parameters = <TlTokenClassParam>[]; |
|
do { |
|
chunksIt.moveNext(); |
|
if (chunksIt.current == '=') { |
|
break; |
|
} |
|
// Params are defined as name:type |
|
// Ignore oddities |
|
if (!chunksIt.current.contains(':')) { |
|
continue; |
|
} |
|
final splitted = chunksIt.current.split(':'); |
|
parameters.add(TlTokenClassParam( |
|
name: splitted[0], |
|
type: splitted[1] |
|
)); |
|
} while (true); |
|
// Finally, there is the base type (abstract class) |
|
chunksIt.moveNext(); |
|
String removeSemicolon(String input) { |
|
while (input.codeUnits.last == ';'.codeUnits[0]) { |
|
input = input.substring(0, input.length - 1); |
|
} |
|
return input; |
|
} |
|
final baseType = removeSemicolon(chunksIt.current); |
|
|
|
yield TlTokenClassTag( |
|
name: name, |
|
parameters: parameters, |
|
baseType: baseType, |
|
); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
class TlTokenFunctionsDelimiter extends TlToken { |
|
@override |
|
String toString() { |
|
return 'TlToken: ---functions---'; |
|
} |
|
} |
|
class TlTokenNone extends TlToken { |
|
@override |
|
String toString() { |
|
return 'TlToken.'; |
|
} |
|
} |
|
class TlTokenCommentLine extends TlToken { |
|
/// The content of the comment including the leading slashes |
|
final String content; |
|
TlTokenCommentLine(this.content); |
|
|
|
@override |
|
String toString() { |
|
return 'TlToken: //$content'; |
|
} |
|
} |
|
class TlTokenCommentTag extends TlToken { |
|
/// The name of the tag, excluding the ampersand: description |
|
final String name; |
|
/// The value of the tag: Provides ... |
|
final String value; |
|
|
|
TlTokenCommentTag({required this.name, required this.value}); |
|
|
|
@override |
|
String toString() { |
|
return 'TlToken: //@$name $value'; |
|
} |
|
} |
|
class TlTokenClassTag extends TlToken { |
|
/// The name of the class |
|
final String name; |
|
final List<TlTokenClassParam> parameters; |
|
final String baseType; |
|
TlTokenClassTag({required this.name, required this.parameters, required this.baseType}); |
|
|
|
@override |
|
String toString() { |
|
final params = parameters.join(', '); |
|
return 'TlToken: $name($params) = $baseType'; |
|
} |
|
} |
|
class TlTokenClassParam { |
|
final String name; |
|
final String type; |
|
TlTokenClassParam({required this.name, required this.type}); |
|
|
|
@override |
|
String toString() { |
|
return '$name:$type'; |
|
} |
|
}
|
|
|