Created
October 28, 2013 13:33
-
-
Save yvt/7196851 to your computer and use it in GitHub Desktop.
Queen HTML ハイライター
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
ArrayList.qn | |
tcpp が 2013年10月28日 に作成. | |
} | |
interface IFormatter`T | |
func Format(v:T): string | |
end interface | |
class ArrayList`T | |
-var arr: []T :: #[4]T | |
-var count: int | |
-var capacity: int :: 4 | |
func EnsureCapacity(cnt: int) | |
var c: int :: capacity | |
while(c < cnt) | |
c :* 2 | |
end while | |
if(c <> capacity) | |
var arr2: []T :: #[c]T | |
for i(0, count - 1) | |
arr2[i] :: arr[i] | |
end for | |
arr :: arr2 | |
capacity :: c | |
end if | |
end func | |
func Add(v: T) | |
EnsureCapacity(count + 1) | |
arr[count] :: v | |
count :+ 1 | |
end func | |
func AddArray(a: []T) | |
EnsureCapacity(count + a.Len()) | |
foreach v(a) | |
arr[count] :: v | |
count :+ 1 | |
end foreach | |
end func | |
func Clear() | |
count :: 0 | |
end func | |
func Get(idx: int): T | |
return arr[idx] | |
end func | |
func Set(idx: int, val: T) | |
arr[idx] :: val | |
end func | |
func GetLen(): int | |
return count | |
end func | |
func ToArray(): []T | |
var arr2: []T :: #[count]T | |
for i(0, count - 1) | |
arr2[i] :: arr[i] | |
end for | |
return arr2 | |
end func | |
func Dump(formatter: IFormatter`T) | |
Dbg@Log("Elements: ------") | |
for i(0, count - 1) | |
Dbg@Log("[" ~ i.ToStr() ~ "] = " ~ formatter.Format(arr[i])) | |
end for | |
Dbg@Log("-----------------") | |
end func | |
end class |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ プログラムのエントリポイントを定義します。 } | |
var text: string:: " | |
{ エラトステネスのふるい実装 } | |
class PrimeGenesis | |
var primes: []int:: #[10000]int | |
var numPrimes: int | |
func Ctor() | |
primes[0] :: 2 | |
numPrimes :: 1 | |
end func | |
-func IsComposite(x: int): bool | |
foreach prime (primes) | |
if( prime = 0 ) | |
return false | |
elif( x % prime = 0 ) | |
return true | |
end if | |
end foreach | |
return false | |
end func | |
func GetNext(): int | |
var i:: primes[numPrimes - 1] + 1 | |
while (IsComposite(i)) | |
i :+ 1 | |
end while | |
primes[numPrimes] :: i | |
numPrimes :+ 1 | |
return i | |
end func | |
end class | |
{ AppMainが定義されると、ゲームエンジンの代わりに呼び出されます。 } | |
func AppMain() | |
var primes:: #PrimeGenesis | |
var sum:: 2 | |
var startTime:: Time@Sys() | |
for (2, 10000) | |
sum :+ primes.GetNext() | |
end for | |
var duration:: (Time@Sys() - startTime)$float / 1000.0 | |
Dbg@Log(\"10000番目までの素数の和 = \" ~ sum.ToStr() ~ \" (\" ~ duration.ToStr() ~ \" 秒)\") | |
Q@Stop() | |
end func | |
" | |
enum KeywordType | |
NotKeyword | |
Type | |
Literal | |
Statement | |
TypeDefinition | |
end enum | |
func ConvertCharIndex(c: char): int | |
switch(c) | |
case ('0' to '9') | |
return c$int - '0'$int | |
case ('a' to 'z') | |
return c$int - 'a'$int + 10 | |
case ('A' to 'Z') | |
return c$int - 'A'$int + 36 | |
case ('_') | |
return 63 | |
end switch | |
return -1 | |
end func | |
class KeywordTree | |
var type: KeywordType | |
var sub: []KeywordTree | |
func Register(str: []char, type: KeywordType, index: int) | |
if(index = str.Len()) | |
this.type :: type | |
return | |
end if | |
if(sub =& null) | |
sub :: #[26 * 2 + 10 + 1]KeywordTree | |
end if | |
var idx:: ConvertCharIndex(str[index]) | |
if(idx = -1) | |
throw 2000, "damemoji! " ~ str | |
end if | |
if(sub[idx] =& null) | |
sub[idx] :: #KeywordTree | |
end if | |
sub[idx].Register(str, type, index + 1) | |
end func | |
func Advance(c: char): KeywordTree | |
if (sub =& null) | |
return null | |
end if | |
var idx:: ConvertCharIndex(c) | |
if (idx = -1) | |
return null | |
end if | |
return sub[idx] | |
end func | |
end class | |
func IsIdentifierChar(c: char): bool | |
switch(c) | |
case ('a' to 'z') | |
return true | |
case ('A' to 'Z') | |
return true | |
case ('_') | |
return true | |
case ('0' to '9') | |
return true | |
default | |
return false | |
end switch | |
end func | |
func AppMain() | |
var code:: text$[]char | |
var root:: #KeywordTree | |
root.Register("byte", KeywordType#Type, 0) | |
root.Register("byte8", KeywordType#Type, 0) | |
root.Register("byte16", KeywordType#Type, 0) | |
root.Register("byte32", KeywordType#Type, 0) | |
root.Register("byte64", KeywordType#Type, 0) | |
root.Register("dict", KeywordType#Type, 0) | |
root.Register("bool", KeywordType#Type, 0) | |
root.Register("float", KeywordType#Type, 0) | |
root.Register("double", KeywordType#Type, 0) | |
root.Register("list", KeywordType#Type, 0) | |
root.Register("queue", KeywordType#Type, 0) | |
root.Register("stack", KeywordType#Type, 0) | |
{ root.Register("func", KeywordType#Type, 0) } | |
root.Register("int", KeywordType#Type, 0) | |
root.Register("int8", KeywordType#Type, 0) | |
root.Register("int16", KeywordType#Type, 0) | |
root.Register("int32", KeywordType#Type, 0) | |
root.Register("int64", KeywordType#Type, 0) | |
root.Register("uint8", KeywordType#Type, 0) | |
root.Register("uint16", KeywordType#Type, 0) | |
root.Register("uint32", KeywordType#Type, 0) | |
root.Register("uint64", KeywordType#Type, 0) | |
root.Register("string", KeywordType#Type, 0) | |
root.Register("char", KeywordType#Type, 0) | |
root.Register("inf", KeywordType#Literal, 0) | |
root.Register("true", KeywordType#Literal, 0) | |
root.Register("this", KeywordType#Literal, 0) | |
root.Register("false", KeywordType#Literal, 0) | |
root.Register("assert", KeywordType#Statement, 0) | |
root.Register("block", KeywordType#Statement, 0) | |
root.Register("break", KeywordType#Statement, 0) | |
root.Register("continue", KeywordType#Statement, 0) | |
root.Register("catch", KeywordType#Statement, 0) | |
root.Register("default", KeywordType#Statement, 0) | |
root.Register("do", KeywordType#Statement, 0) | |
root.Register("elif", KeywordType#Statement, 0) | |
root.Register("else", KeywordType#Statement, 0) | |
root.Register("end", KeywordType#Statement, 0) | |
root.Register("finally", KeywordType#Statement, 0) | |
root.Register("for", KeywordType#Statement, 0) | |
root.Register("foreach", KeywordType#Statement, 0) | |
root.Register("func", KeywordType#Statement, 0) | |
root.Register("if", KeywordType#Statement, 0) | |
root.Register("ifdef", KeywordType#Statement, 0) | |
root.Register("return", KeywordType#Statement, 0) | |
root.Register("rls", KeywordType#Statement, 0) | |
root.Register("dbg", KeywordType#Statement, 0) | |
root.Register("skip", KeywordType#Statement, 0) | |
root.Register("switch", KeywordType#Statement, 0) | |
root.Register("case", KeywordType#Statement, 0) | |
root.Register("throw", KeywordType#Statement, 0) | |
root.Register("to", KeywordType#Statement, 0) | |
root.Register("try", KeywordType#Statement, 0) | |
root.Register("var", KeywordType#Statement, 0) | |
root.Register("while", KeywordType#Statement, 0) | |
root.Register("const", KeywordType#Statement, 0) | |
root.Register("class", KeywordType#Statement, 0) | |
root.Register("enum", KeywordType#Statement, 0) | |
root.Register("interface", KeywordType#Statement, 0) | |
enum BlockState | |
Normal | |
StringLiteral | |
CharLiteral | |
end enum | |
func EmitKeywordSpan(type: KeywordType): []char | |
switch(type) | |
case(KeywordType#Type) | |
return "<span class=\"kwType\">" | |
case(KeywordType#Statement) | |
return "<span class=\"kwStatement\">" | |
case(KeywordType#Literal) | |
return "<span class=\"kwLiteral\">" | |
default | |
assert false | |
end switch | |
return null | |
end func | |
func EmitBlockSpan(type: BlockState): []char | |
switch(type) | |
case(BlockState#StringLiteral) | |
return "<span class=\"bString\">" | |
case(BlockState#CharLiteral) | |
return "<span class=\"bChar\">" | |
default | |
assert false | |
end switch | |
return null | |
end func | |
func EmitChar(arr: ArrayList@ArrayList`char, c: char) | |
switch(c) | |
case ('<') | |
arr.AddArray("<") | |
case ('>') | |
arr.AddArray(">") | |
case ('"') | |
arr.AddArray(""") | |
default | |
arr.Add(c) | |
end switch | |
end func | |
var output:: #ArrayList@ArrayList`char | |
var token:: #ArrayList@ArrayList`char | |
var commentDepth:: 0 | |
var state:: BlockState#Normal | |
var tree: KeywordTree:: null | |
var scanningIdentifier:: false | |
for i(0, code.Len() - 1) | |
var c:: code[i] | |
if(commentDepth > 0) | |
output.Add(c) | |
if(c = '}') | |
commentDepth :- 1 | |
if(commentDepth = 0) | |
output.AddArray("</span>") | |
end if | |
elif(c = '{') | |
commentDepth :+ 1 | |
end if | |
else | |
switch(state) | |
case (BlockState#Normal) | |
if(IsIdentifierChar(c)) | |
if(scanningIdentifier) | |
token.Add(c) | |
tree :: (tree =& null) ? (null, tree.Advance(c)) | |
else | |
tree :: root.Advance(c) | |
token.Add(c) | |
scanningIdentifier :: true | |
end if | |
else | |
if(scanningIdentifier) | |
if(tree <>& null & tree.type <> KeywordType#NotKeyword) | |
output.AddArray(EmitKeywordSpan(tree.type)) | |
output.AddArray(token.ToArray()) | |
output.AddArray("</span>") | |
token.Clear() | |
else | |
output.AddArray(token.ToArray()) | |
token.Clear() | |
end if | |
end if | |
tree :: null | |
scanningIdentifier :: false | |
switch(c) | |
case ('{') | |
commentDepth :+ 1 | |
output.AddArray("<span class=\"codeComment\">") | |
case ('"') | |
state :: BlockState#StringLiteral | |
output.AddArray(EmitBlockSpan(state)) | |
case ('\'') | |
state :: BlockState#CharLiteral | |
output.AddArray(EmitBlockSpan(state)) | |
end switch | |
output.Add(c) | |
end if | |
case (BlockState#StringLiteral) | |
EmitChar(output, c) | |
if(c = '\\') | |
i :+ 1 | |
EmitChar(output, code[i]) | |
elif(c = '"') | |
state :: BlockState#Normal | |
output.AddArray("</span>") | |
end if | |
case (BlockState#CharLiteral) | |
EmitChar(output, c) | |
if(c = '\\') | |
i :+ 1 | |
EmitChar(output, code[i]) | |
elif(c = '\'') | |
state:: BlockState#Normal | |
output.AddArray("</span>") | |
end if | |
default | |
assert false | |
end switch | |
end if | |
end for | |
Dbg@Log(output.ToArray()) | |
Q@Stop() | |
end func |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment