# HG changeset patch # User Mike Pavone # Date 1240988283 14400 # Node ID 73e978d590c7b0b778b758d7ae85c6d49bd57f72 # Parent b3f71490858cfcd46cd4098aa77515ceff719700 Adding WIP compiler code diff -r b3f71490858c -r 73e978d590c7 cbackend.rhope --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cbackend.rhope Wed Apr 29 02:58:03 2009 -0400 @@ -0,0 +1,84 @@ + +Blueprint Blueprint Def +{ + Name + Fixed Size + Fields + Methods +} + +Blueprint Def[name] +{ + out <- [[[[Build["Blueprint Def"]]Name <<[name]]Fixed Size <<[0]]Fields <<[()]]Methods <<[New@Dictionary[]] +} + +Blueprint C Function +{ + Name + Inputs + Outputs + Convention + Variables + Statements +} + +C Function[name,inputs,outputs,convention:out] +{ + out <- [[[[[[Build["C Function"] + ]Name <<[name] + ]Inputs <<[inputs] + ]Outputs <<[outputs] + ]Convention <<[convention] + ]Variables <<[New@Dictionary[]] + ]Statements <<[()] +} + +Allocate Var@C Function[func,name,type:out] +{ + out <- [func]Variables <<[ [[func]Variables >>]Set[name,type] ] +} + +Add Statement@C Function[func,statement:out] +{ + out <- [func]Statements <<[ [[func]Statements >>]Append[[statement]Append[";"]] ] +} + +Add Operator Statement@C Function[func,source1,source2,dest,op:out] +{ + out <- [func]Add Statement[[[[[dest]Append[" = "]]Append[source1]]Append[op]]Append[source2]] +} + +Add@C Function[func,source1,source2,dest:out] +{ + out <- [func]Add Operator Statement[source1,source2,dest," + "] +} + +Sub@C Function[func,source1,source2,dest:out] +{ + out <- [func]Add Operator Statement[source1,source2,dest," - "] +} + +Multiply@C Function[func,source1,source2,dest:out] +{ + out <- [func]Add Operator Statement[source1,source2,dest," * "] +} + +Divide@C Function[func,source1,source2,dest:out] +{ + out <- [func]Add Operator Statement[source1,source2,dest," / "] +} + +Move@C Function[func,source,dest:out] +{ + out <- [func]Add Statement[[[dest]Append[" = "]]Append[source]] +} + +Definitions@C Function[func:out] +{ + +} + +Text@C Function[func:out] +{ + +} \ No newline at end of file diff -r b3f71490858c -r 73e978d590c7 compile.rhope --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/compile.rhope Wed Apr 29 02:58:03 2009 -0400 @@ -0,0 +1,17 @@ +Import lex.rhope +Import countstring.rhope +Import parse.rhope + +Main[args] +{ + [args]Index[1] + { + Print[["Parsing "]Append[~]] + file <- "] + } +} diff -r b3f71490858c -r 73e978d590c7 countstring.rhope --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/countstring.rhope Wed Apr 29 02:58:03 2009 -0400 @@ -0,0 +1,106 @@ + +Blueprint Count String +{ + Text + Line + Column +} + +Count String[text:out] +{ + out <- Count String At Pos[text, 0, 0] +} + +Count String At Pos[text,line,col:out] +{ + out <- [[[Build["Count String"]]Text <<[text]]Line <<[line]]Column <<[col] +} + +Slice@Count String[string,index:left,right] +{ + + If[[index] = [0]] + { + left <- [string]Text <<[""] + right <- Val[string] + }{ + ltext,rtext <- [[string]Text >>]Slice[index] + left <- [string]Text <<[ltext] + parts <- [ltext]Split["\n"] + last line <- [[parts]Length] - [1] + rline <- [[string]Line >>] + [last line] + prercol <- [[parts]Index[last line]]Length + If[[last line] > [0]] + { + rcol <- Val[prercol] + }{ + rcol <- [prercol] + [[string]Column >>] + } + right <- Count String At Pos[rtext, rline, rcol] + } +} + +Length@Count String[string:out] +{ + out <- Length[[string]Text >>] +} + +Append@Count String[left,right:out] +{ + If[[[left]Length] > [0]] + { + out <- [left]Text << [ [To String[left]]Append[To String[right]] ] + }{ + out <- right + } +} + +=@Count String[left,right:out] +{ + out <- [To String[left]] = [To String[right]] +} + +Get DString@Count String[string, delims:after,before,delim,nomatch] +{ + ,,delim,nomatch <- [[string]Text >>]Get DString[delims] + { + If[[dlines] > [0]] + { + cols <- Val[dcols] + }{ + If[[blines] > [0]] + { + cols <- [bcols] + [dcols] + }{ + cols <- [[bcols] + [dcols]] + [[string]Column >>] + } + } + after <- Count String At Pos[~, [[blines]+[dlines]] + [[string]Line >>], cols] + }{ + before <- [string]Text <<[~] + bparts <- [~]Split["\n"] + preblines <- [[bparts]Length] - [1] + If[[preblines] > [-1]] + { + blines <- Val[preblines] + bcols <- Length[[bparts]Index[blines]] + }{ + bcols <- 0 + blines <- 0 + } + }{ + dparts <- [~]Split["\n"] + dlines <- [[dparts]Length] - [1] + dcols <- Length[[dparts]Index[dlines]] + } +} + +To String@Count String[string:out] +{ + out <- [string]Text >> +} + +Empty@Count String[string:out] +{ + out <- Count String[""] +} diff -r b3f71490858c -r 73e978d590c7 genasm.rhope --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/genasm.rhope Wed Apr 29 02:58:03 2009 -0400 @@ -0,0 +1,940 @@ +//Import extendlib.rhope +Escape Rhope Name[name:escaped] +{ + escaped <- [[[[[[[[[name]Replace["_","__"] + ]Replace["@","_AT_"] + ]Replace[" ","_SP_"] + ]Replace[":","_CN_"] + ]Replace["?","_QN_"] + ]Replace["+","_PL_"] + ]Replace["-","_MN_"] + ]Replace["*","_TM_"] + ]Replace["/","_DV_"] +} + +Blueprint Registers +{ + Names + Can Data + Can Pointer + Available? + Need Save + Max Size +} + +Set Yes[in:out] +{ + out <- Yes +} + +_Flip[dest,val,index:out] +{ + out <- [dest]Set[val,index] +} +Flip[list,dest:out] +{ + out <- Fold["_Flip", dest, list] +} + +Registers[names, data, pointer, need save, max size:out] +{ + out <- [[[[[[Build["Registers"] + ]Names << [names] + ]Can Data << [data] + ]Can Pointer << [pointer] + ]Available? << [ Map[names, "Set Yes"] ] + ]Need Save << [ Flip[need save, ()] ] + ]Max Size <<[max size] +} + +Name@Registers[regs,num:out] +{ + out <- [[regs]Names >>]Index[num] +} + +Allocate Helper@Registers[regs, try, current:found, not found] +{ + reg <- [try]Index[current] + If[[[regs]Available? >>]Index[reg]] + { + found <- Val[reg] + }{ + [try]Next[current] + { + found, not found <- [regs]Allocate Helper[try, ~] + }{ + not found <- Yes + } + } +} + +Allocate Reg@Registers[regs,try:next regs,found,need save?,not found] +{ + [try]First + { + found, not found <- [regs]Allocate Helper[try, ~] + { + next regs <- [regs]Available? << [ [[regs]Available? >>]Set[~, No] ] + [[regs]Need Save >>]Index[~] + { + need save? <- Yes + }{ + need save? <- No + } + } + }{ + not found <- Yes + } +} + +Free Reg@Registers[regs,num:out] +{ + out <- [regs]Available? <<[ [[regs]Available? >>]Set[num, Yes] ] +} + +Processor Reg[func,type:next func,num,not found] +{ + regs <- [func]Registers >> + If[[type] = ["pointer"]] + { + source <- [regs]Can Pointer >> + }{ + source <- [regs]Can Data >> + } + next regs, reg num, need save?, not found <- [regs]Allocate Reg[source] {} + { + If[need save?] + { + next func <- [[func]Need Save << [ [[func]Need Save >>]Set[reg num, Yes] ] + ]Registers << [next regs] + }{ + next func <- [func]Registers << [next regs] + } + num <- Val[reg num] + } +} + +Processor Free Reg[func,num:out func] +{ + out func <- [func]Registers <<[ [[func]Registers >>]Free Reg[num] ] +} + +Processor Allocate[func,name,size,type:out func,out] +{ + regs <- [func]Registers >> + If[[type] = ["pointer"]] + { + alloc size <- [func]Pointer Size + }{ + alloc size <- size + } + If[[alloc size] > [[regs]Max Size >>]] { + stack alloc <- Val[alloc size] + }{ + next func <- [func]Processor Reg[type] {} + { + location <- Register[~, alloc size] + }{ + stack alloc <- Val[alloc size] + } + } + Val[stack alloc] + { + next func, location <- [func]Allocate Stack[alloc size] + } + out func <- [next func]Variables <<[ [[next func]Variables >>]Set[name, location] ] + out <- Val[location] +} + +Blueprint Register +{ + Number + Value Size +} +Register[num,size:out] +{ + If[[size] = [3]] + { + value size <- 4 + }{ + value size <- size + } + out <- [[Build["Register"]]Number <<[num]]Value Size <<[value size] +} + +In Memory?@Register[reg:out] +{ + out <- No +} + +=@Register[reg,other:out] +{ + ,out <- If[[Type Of[reg]] = [Type Of[other]]] + { + out <- [[reg]Number >>] = [[other]Number >>] + } +} + +Op ASM@Register[reg,func,regs,extra offset:out] +{ + out <- [regs]Index[ [reg]Number >> ] +} + +Size@Register[reg:out] +{ + out <- [reg]Value Size >> +} + +Blueprint Immediate +{ + Value +} + +Immediate[val:out] +{ + out <- [Build["Immediate"]]Value <<[val] +} + +In Memory?@Immediate[val:out] +{ + out <- No +} + +=@Immediate[val,other:out] +{ + ,out <- If[[Type Of[val]] = [Type Of[other]]] + { + out <- [[val]Value >>] = [[other]Value >>] + } +} + +Op ASM@Immediate[val,func,regs,extra offset:out] +{ + out <- [val]Value >> +} + +Size@Immediate[val:out] +{ + out <- 4 +} + +Blueprint None +{ + Dummy +} + +None[:out] +{ + out <- Build["None"] +} + +In Memory?@None[none:out] +{ + out <- No +} + +Op ASM@None[none,func,regs,extra offset:out] +{ + out <- "" +} + +Size@None[none:out] +{ + out <- 0 +} + +Blueprint Stack Location +{ + Offset + Size +} + +Stack Location[offset,size:out] +{ + out <- [[Build["Stack Location"]]Offset <<[offset]]Size <<[size] +} + +In Memory?@Stack Location[location:out] +{ + out <- Yes +} + +=@Stack Location[loc,other:out] +{ + ,out <- If[[Type Of[loc]] = [Type Of[other]]] + { + out <- [[loc]Offset >>] = [[other]Offset >>] + } +} + +Op ASM@Stack Location[loc,func,regs,extra offset:out] +{ + offset <- [[[func]Stack Size >>] - [[loc]Offset >>]] - [[loc]Size >>] + If[[offset] > [0]] + { + toffset <- ["+"]Append[offset] + }{ + toffset <- "" + } + out <- [["[esp"]Append[toffset]]Append["]"] +} + +Size@Stack Location[loc:out] +{ + out <- [loc]Size >> +} + +Blueprint Pointer +{ + Base + Offset + Target Size +} + +Pointer[base,offset,size:out] +{ + out <- [[[Build["Pointer"]]Base <<[base]]Offset <<[offset]]Target Size <<[size] +} + +In Memory?@Pointer[location:out] +{ + out <- Yes +} + +=@Pointer[pointer,other:out] +{ + ,out <- If[[Type Of[loc]] = [Type Of[other]]] + { + out <- [[loc]Storage >>] = [[other]Storage >>] + } +} + +Op ASM@Pointer[pointer,func,regs,extra offset:out] +{ + If[[Type Of[ [pointer]Offset >> ]] = ["None"]] + { + out <- [["["]Append[ [[pointer]Base >>]Op ASM[func,regs,extra offset] ]]Append["]"] + }{ + out <- [[[["[" + ]Append[ [[pointer]Base >>]Op ASM[func,regs,extra offset] ] + ]Append["+"] + ]Append[ [[pointer]Offset >>]Op ASM[func,regs,extra offset] ] + ]Append["]"] + } +} + +Size@Pointer[pointer:out] +{ + out <- [pointer]Target Size >> +} + +Blueprint X86 Instruction +{ + Name + Op1 + Op2 + Width + Extra Offset +} + +X86 Instruction[name, op1, op2, width:out] +{ + out <- [[[[[Build["X86 Instruction"]]Name << [name]]Op1 << [op1]]Op2 <<[op2]]Width <<[width]]Extra Offset <<[0] +} + +CAppend[left,right:out] +{ + If[[right] = [""]] + { + out <- "" + }{ + out <- [left]Append[right] + } +} + +Inst ASM@X86 Instruction[inst,func:out] +{ + If[[[inst]Width >>] = [4]] + { + regs <- ("eax","ecx","edx","ebx","esi","edi","esp") + }{ + If[[[inst]Width >>] = [2]] + { + regs <- ("ax","cx","dx","bx","si","di") + }{ + regs <- ("al","cl","dl","bl","si","di") + } + } + out <- [[[inst]Name >> + ]Append[ [" "]CAppend[[[inst]Op1>>]Op ASM[func, regs, [inst]Extra Offset >>]] ] + ]Append[ [", "]CAppend[[[inst]Op2>>]Op ASM[func, regs, [inst]Extra Offset >>]] ] +} + +Blueprint X86 Function +{ + Name + Registers + Variables + Scratch + Need Save + Free Stack Locations + Stack Size + Param Size + Temp Stack + Convention + Instructions +} + +X86 Function[name,params,convention:out] +{ + [[[[[[[[[Build["X86 Function"] + ]Name << [name] + ]Registers << [Registers[("eax","ecx","edx","ebx","esi","edi"), (0,1,2,3,4,5), (0,1,2,3,4,5), (3,4,5), 4]] + ]Variables <<[New@Dictionary[]] + ]Need Save <<[()] + ]Free Stack Locations <<[()] + ]Stack Size <<[0] + ]Instructions <<[()] + ]Convention <<[convention] + ]Alloc Params[params, convention] + { + out <- [~]Param Size <<[ [~]Stack Size >> ] + } +} + +Pointer Size@X86 Function[func:out] +{ + out <- 4 +} + +Param Helper@X86 Function[func, param:out] +{ + ,loc <- [func]Allocate Stack[4] + { + out <- [~]Variables << [ [[~]Variables >>]Set[param, loc] ] + } +} + +Alloc Params@X86 Function[func,params,convention:out] +{ + If[[convention] = ["fastcall"]] + { + [params]Index[0] + { + next func <- [[func]Registers <<[ [[func]Registers >>]Available? <<[ [[[func]Registers >>]Available? >>]Set[1, No] ]] + ]Variables <<[ [[func]Variables >>]Set[~, Register[1,4]] ] + [params]Index[1] + { + next func2 <- [[next func]Registers <<[ [[next func]Registers >>]Available? <<[ [[[next func]Registers >>]Available? >>]Set[2, No] ]] + ]Variables <<[ [[next func]Variables >>]Set[~, Register[2,4]] ] + [params]Index[2] + { + out <- _Fold[params, 2, next func2, "Param Helper"] + }{ + out <- Val[next func2] + } + }{ + out <- Val[next func] + } + }{ + out <- func + } + }{ + out <- Fold["Param Helper", func, params] + } +} + +Add Instruction@X86 Function[func, inst:out] +{ + out <- [func]Instructions << [ [[func]Instructions >>]Append[ [inst]Extra Offset <<[[func]Temp Stack >>] ] ] +} + +Allocate Stack@X86 Function[func,size:func out,out] +{ + out <- Stack Location[[func]Stack Size >>, size] + func out <- [func]Stack Size <<[ [[func]Stack Size >>]+[size] ] +} + +Allocate Var@X86 Function[func,name,size,type:out func,out] +{ + out func, out <- Processor Allocate[func,name,size,type] +} + +Resolve@X86 Function[func,op:out,out func] +{ + If[[Type Of[op]] = ["String"]] + { + out <- [[func]Variables >>]Index[op] + }{ + out <- op + } +} + +Allocate Scratch@X86 Function[func,size:out func,scratch] +{ + out func,scratch <- Processor Reg[func,"data"] {} {} + { + //FIXME: need to use a reg that's not involved in the current op + //FIXME: Also, might need two scratch regs and both might be in use + ,stack inc <- [func]Save Reg[0] + { + out func <- [~]Scratch << [ [[~]Scratch >>]Set[0, Yes] ] + } + } +} + +Free Scratch@X86 Function[func,scratch:out func] +{ + [[func]Scratch >>]Index[scratch] + { + [func]Restore Reg[scratch] + { + out func <- [~]Scratch << [ [[~]Scratch >>]Remove[scratch] ] + } + }{ + out func <- Processor Free Reg[func, scratch] + } + If[[scratch]Index[1]] + { + + }{ + + } +} + +Classify Op@X86 Function[func,op:class] +{ + If[[op]In Memory?] + { + If[[Type Of[op]] = ["Pointer"]] + { + If[[[[op]Base >>]In Memory?] Or [[[op]Offset >>]In Memory?]] + { + class <- "u" + }{ + class <- "m" + } + }{ + class <- "m" + } + }{ + class <- "r" + } +} + +RegMem2Op@X86 Function[func,dest,notdest,op,size:out] +{ + out <- [func]Add Instruction[X86 Instruction[op, dest, notdest, size]] +} + +MemPointer2Op@X86 Function[func,dest,notdest,op,size:out] +{ + ,scratch <- [func]Allocate Scratch[size] + { + out <- [[[~]Fetch[notdest,scratch] + ]Add Instruction[X86 Instruction[op, dest, scratch, size]] + ]Free Scratch[scratch] + } +} + +//Make sure to map this to both r, (m or r) -> m and r, (m or r) -> r +RegMemToNotPointer@X86 Function[func,source1,source2,dest,op,size:out] +{ + out <- [[func]Move[source2,dest] + ]Add Instruction[X86 Instruction[op, dest, source1, size]] +} + +RegMemToPointer@X86 Function[func,source1,source2,dest,op,size:out] +{ + ,scratch <- [func]Allocate Scratch[size] + { + spointer <- Pointer[scratch, None[], size] + out <- [[[[~]Calculate Address[dest, scratch] + ]Move[source2, spointer] + ]Add Instruction[X86 Instruction[op, spointer, source1, size]] + ]Free Scratch[scratch] + } +} + +RegPointerToMem@X86 Function[func,source1,source2,dest,op,size:out] +{ + ,scratch <- [func]Allocate Scratch[size] + { + spointer <- Pointer[scratch, None[], size] + out <- [[[[~]Calculate Address[source2, scratch] + ]Move[spointer, dest] + ]Add Instruction[X86 Instruction[op, dest, source1, size]] + ]Free Scratch[scratch] + } +} + +RegPointerReg2Op@X86 Function[func,dest,notdest,op,size:out] +{ + ,scratch <- [func]Allocate Scratch[size] + { + spointer <- Pointer[scratch, None[], size] + out <- [[[~]Calculate Address[notdest, scratch] + ]Add Instruction[X86 Instruction[op, dest, spointer, size]] + ]Free Scratch[scratch] + } +} + +RegPointerPointer2Op@X86 Function[func,dest,notdest,op,size:out] +{ + ,scratch <- [func]Allocate Scratch[size] + { + spointer <- Pointer[scratch, None[], size] + out <- [[[~]Calculate Address[dest, scratch] + ]Add Instruction[X86 Instruction[op, spointer, notdest, size]] + ]Free Scratch[scratch] + } +} + +RegPointerToPointer@X86 Function[func,source1,source2,dest,op,size:out] +{ + ,scratch <- [func]Allocate Scratch[size] + { + spointer <- Pointer[scratch, None[], size] + ,scratch2 <- [~]Allocate Scratch[size] + { + spointer2 <- Pointer[scratch2, None[], size] + out <- [[[[[[~]Calculate Address[source2, scratch] + ]Calculate Address[dest, scratch2] + ]Move[spointer2, spointer] + ]Add Instruction[X86 Instruction[op, spointer2, source1, size]] + ]Free Scratch[scratch2] + ]Free Scratch[scratch] + } + } +} + +//If source1, source2 and dest are all pointers with register offsets, allocating a scratch register could +//become a problem unless I let ebp be used as a scratch register. Should be doable as long as thread local +//variables properly report ebp as a used register. Alternatively, one register could be reserved for scratch +//usage +MemPointerToMem@X86 Function[func,source1,source2,dest,op,size:out] +{ + ,scratch <- [func]Allocate Scratch[size] + { + out <- [[[[~]Fetch[source2, scratch] + ]Add Instruction[X86 Instruction[op, scratch, source1, size]] + ]Move[scratch, dest] + ]Free Scratch[scratch] + } +} + +MemPointerToPointer@X86 Function[func,source1,source2,dest,op,size:out] +{ + ,scratch <- [func]Allocate Scratch[size] + { + ,scratch2 <- [~]Allocate Scratch[size] + { + spointer2 <- Pointer[scratch2, None[], size] + out <- [[[[[[~]Fetch[source2, scratch] + ]Add Instruction[X86 Instruction[op, scratch, source1, size]] + ]Calculate Address[dest, scratch2] + ]Move[scratch, spointer2] + ]Free Scratch[scratch2] + ]Free Scratch[scratch] + } + } +} + +//This does almost the same thing as RegMemToNotPointer, depending on how I do the pattern matching I could maybe combine them +PointerMemToReg@X86 Function[func,source1,source2,dest,op,size:out] +{ + out <- [[func]Fetch[source1,dest] + ]Add Instruction[X86 Instruction[op, dest, source2, size]] +} + +PointerPointer2Op@X86 Function[func,dest,notdest,op,size:out] +{ + ,scratch <- [func]Allocate Scratch[size] + { + spointer <- Pointer[scratch, None[], size] + ,scratch2 <- [~]Allocate Scratch[size] + { + out <- [[[[[[[~]Calculate Address[dest, scratch] + ]Fetch[notdest, scratch2] + ]Add Instruction[X86 Instruction[op, scratch, scratch2, size]] + ]Calculate Address[dest, scratch2] + ]Move[scratch, spointer2] + ]Free Scratch[scratch2] + ]Free Scratch[scratch] + } + } +} + +PointerPointerToPointer@X86 Function[func,source1,source2,dest,op,size:out] +{ + ,scratch <- [func]Allocate Scratch[size] + { + ,scratch2 <- [~]Allocate Scratch[size] + { + spointer2 <- Pointer[scratch2, None[], size] + out <- [[[[[[[~]Fetch[source1, scratch] + ]Calculate Address[source2, scratch2] + ]Add Instruction[X86 Instruction[op, scratch, spointer2, size]] + ]Calculate Address[dest, scratch2] + ]Move[scratch, spointer2] + ]Free Scratch[scratch2] + ]Free Scratch[scratch] + } + } +} + +PointerPointerToMem@X86 Function[func,source1,souce2,dest,op,size:out] +{ + ,scratch <- [func]Allocate Scratch[size] + { + spointer <- Pointer[scratch, None[], size] + out <- [[[[[~]Calculate Address[source1, scratch] + ]Move[dest, spointer] + ]Fetch[source2, scratch] + ]Add Instruction[X86 Instruction[op, dest, scratch, size]] + ]Free Scratch[scratch] + } +} + +PointerPointerToReg@X86 Function[func,source1,souce2,dest,op,size:out] +{ + ,scratch <- [func]Allocate Scratch[size] + { + spointer <- Pointer[scratch, None[], size] + out <- [[[[~]Fetch[source1, dest] + ]Calculate Address[source2, scratch] + ]Add Instruction[X86 Instruction[op, dest, scratch, size]] + ]Free Scratch[scratch] + } +} + +2Op Associative@X86 Function[func,psource1,psource2,pdest,name:out func] +{ + source1 <- [func]Resolve[psource1] + source2 <- [func]Resolve[psource2] + dest <- [func]Resolve[pdest] + dest class <- [func]Classify Op[dest] + width <- Min[Min[Min[[source1]Size,[source2]Size], [dest]Size], 4] + swapper <- (1,0) + sources <- [[()]Append[source1]Append[source2] + [sources]Find[dest] + { + source <- [swapper]Index[~] + source class <- [func]Classify Op[source] + If[[dest class] = ["u"]] + { + If[[source class] = ["r"]] + { + out func <- [func]RegPointerPointer2Op[dest,source,name,width] + }{ + out func <- [func]PointerPointer2Op[dest,source,name,width] + } + }{ + If[[dest class] = ["r"]] + { + If[[source class] = ["u"]] + { + out func <- [func]RegPointerReg2Op[dest,source,name,width] + }{ + out func <- [func]RegMem2Op[dest,source,name,width] + } + }{ + If[[source class] = ["r"]] + { + out func <- [func]RegMem2Op[dest,source,name,width] + }{ + out func <- [func]MemPointer2Op[dest,source,name,width] + } + } + } + }{ + sclasses <- Map[sources, ["Classify Op"]Set Input[0, func]] + first <- [sources]Index[found index] + other index <- [swapper]Index[found index] + other <- [sources]Index[other index] + other class <- [sclasses]Index[other index] + found index <- [sclasses]Find["r"] + { + If[[other class] = ["u"]] + { + If[[dest class] = ["m"]] + { + out func <- [func]RegPointerToMem[first,other,dest,name,width] + }{ + If[[dest class] = ["u"]] + { + out func <- [func]RegPointerToPointer[first,other,dest,name,width] + }{ + out func <- [func]PointerMemToReg[other,first,dest,name,width] + } + } + }{ + If[[dest class] = ["u"]] + { + out func <- [func]RegMemToPointer[first,other,dest,name,width] + }{ + out func <- [func]RegMemToNotPointer[first,other,dest,name,width] + } + } + }{ + found index <- [sclasses]Find["m"] + { + If[[dest class] = ["r"]] + { + out func <- [func]PointerMemToReg[other,first,dest,name,width] + }{ + If[[dest class] = ["m"]] + { + out func <- [func]MemPointerToMem[first,other,dest,name,width] + }{ + out func <- [func]MemPointerToPointer[first,other,dest,name,width] + } + } + }{ + If[[dest class] = ["r"]] + { + out func <- [func]PointerPointerToReg[first,other,dest,name,width] + }{ + If[[dest class] = ["m"]] + { + out func <- [func]PointerPointerToMem[first,other,dest,name,width] + }{ + out func <- [func]PointerPointerToPointer[first,other,dest,name,width] + } + } + } + } + } +} + +2Op@X86 Function[func,psource1,psource2,pdest,name:out func] +{ + source1 <- [func]Resolve[psource1] + source2 <- [func]Resolve[psource2] + dest <- [func]Resolve[pdest] + width <- Min[Min[Min[[source1]Size,[source2]Size], [dest]Size], 4] + If[[source1] = [dest]] + { + If[[[source1]In Memory?] And [[source2]In Memory?]] + { + ,scratch, stack inc <- [func]Allocate Scratch[width] + { + out func <- [[[~]Add Instruction[X86 Instruction["mov", [scratch]Index[0], source2, width, stack inc]] + ]Add Instruction[X86 Instruction[name, source1, [scratch]Index[0], width, stack inc]] + ]Free Scratch[scratch] + } + }{ + out func <- [func]Add Instruction[X86 Instruction[name, dest, source2, width, 0]] + } + }{ + If[[dest]In Memory?] + { + If[[source2]In Memory?] + { + ,scratch, stack inc <- [func]Allocate Scratch[width] + { + out func <- [[[[~]Add Instruction[X86 Instruction["mov", [scratch]Index[0], source1, width, stack inc]] + ]Add Instruction[X86 Instruction[name, [scratch]Index[0], source2, width, stack inc]] + ]Add Instruction[X86 Instruction["mov", dest, [scratch]Index[0], width, stack inc]] + ]Free Scratch[scratch] + } + }{ + out func <- [[func]Move[source1,dest] + ]Add Instruction[X86 Instruction[name, dest, source2, width, 0]] + } + }{ + out func <- [[func]Move[source1,dest] + ]Add Instruction[X86 Instruction[name, dest, source2, width, 0]] + } + } +} + +Add@X86 Function[func,source1,source2,dest:out func] +{ + out func <- [func]2Op Associative[source1,source2,dest,"add"] +} + +Sub@X86 Function[func,source1,source2,dest:out func] +{ + out func <- [func]2Op[source1,source2,dest,"sub"] +} + +Move@X86 Function[func,psource,pdest:out func] +{ + source <- [func]Resolve[psource] + dest <- [func]Resolve[pdest] + out func <- [func]Add Instruction[X86 Instruction["mov", dest, source, 4]] +} + +Instruction ASM[current,instruction,func:out] +{ + out <- [[[current]Append["\t"]]Append[ [instruction]Inst ASM[func] ]]Append["\n"] +} + +Save Reg@X86 Function[func,reg:out] +{ + out <- [[func]Add Instruction[X86 Instruction["push", Register[reg, 4], None[], 4]] + ]Temp Stack << [ [[func]Temp Stack >>]+[4] ] +} + +Prolog Save@X86 Function[func,junk,reg:out] +{ + out <- [[func]Add Instruction[X86 Instruction["push", Register[reg, 4], None[], 4]] + ]Stack Size << [ [[func]Stack Size >>]+[4] ] +} + +Restore Reg@X86 Function[func,reg:out] +{ + out <- [[func]Add Instruction[X86 Instruction["pop", Register[reg, 4], None[], 4]] + ]Temp Stack << [ [[func]Temp Stack >>]-[4] ] +} + +Epilogue Restore@X86 Function[func,junk,reg:out] +{ + out <- [func]Add Instruction[X86 Instruction["pop", Register[reg, 4], None[], 4]] +} + +Finalize@X86 Function[func:out] +{ + alloc stack <- [[func]Stack Size >>] - [[func]Param Size >>] + + oldstream <- [func]Instructions >> + + If[[alloc stack] > [0]] + { + start <- [()]Append[X86 Instruction["sub", Register[6, 4],Immediate[alloc stack], Register[6, 4], 4], func] + }{ + start <- () + } + + If[[[func]Convention >>] = ["cdecl"]] + { + If[ [alloc stack] > [0] ] + { + retparam <- Immediate[alloc stack] + }{ + retparam <- None[] + } + }{ + retparam <- Immediate[[func]Stack Size >>] + } + + [[func]Need Save >>]First + { + prolog <- Fold["Prolog Save", [func]Instructions << [start], [func]Need Save >>] + out <- [Reverse Fold["Epilogue Restore", body, [func]Need Save >>]]Add Instruction[X86 Instruction["ret", retparam, None[], 4]] + }{ + prolog <- [func]Instructions <<[start] + out <- [body]Add Instruction[X86 Instruction["ret", retparam, None[], 4]] + } + + body <- Fold["Add Instruction", prolog, oldstream] +} + +Text@X86 Function[func:out] +{ + name line <- [Escape Rhope Name[[func]Name >>] + ]Append[":\n"] + + out <- Fold[["Instruction ASM"]Set Input[2, func], name line, [func]Instructions >>] +} diff -r b3f71490858c -r 73e978d590c7 lex.rhope --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lex.rhope Wed Apr 29 02:58:03 2009 -0400 @@ -0,0 +1,188 @@ +Import extendlib.rhope + +Blueprint Token +{ + Type + Raw Text + Text +} + +Token[type,raw,text:out] +{ + out <- [[[Build["Token"]]Type <<[type]]Raw Text <<[raw]]Text <<[text] +} + +_Type Match[val, test type, type:out] +{ + If[[test type]=[type]] + { + out <- Yes + }{ + out <- Val[val] + } +} + +Type Match@Token[token,type:match,nomatch] +{ + match,nomatch <- If[Fold[["_Type Match"]Set Input[2, [token]Type >>], No, As List[type]]] +} + +String Literal[string, raw string, escapes, text, simple tokens, token list:out] +{ + first,rest <- [text]Slice[1] + If[[first] = ["\""]] + { + out <- _Lex[rest, [first]Slice[0], simple tokens, [token list]Append[Token["String Literal", raw string, string]]] + }{ + next raw <- [raw string]Append[first] + If[[first] = ["\\"]] + { + second,next text <- [rest]Slice[1] + char <- [escapes]Index[To String[second]] {} + { + char <- Val[second] + } + next string <- [string]Append[char] + }{ + next string <- [string]Append[first] + next text <- Val[rest] + } + out <- String Literal[next string, next raw, escapes, next text, simple tokens, token list] + } +} + +Line Comment[start comment, text, simple tokens, token list:out] +{ + next text, comment <- [text]Get DString["\n"] {} {} {} + { + next text <- "" + } + out <- _Lex[next text, [next text]Slice[0], simple tokens, [token list]Append[Token["Line Comment", [start comment]Append[comment], comment]]] + +} + +Block Comment[comment,raw comment, depth, text, simple tokens, token list:out] +{ + Print[["Block Comment: Depth="]Append[depth]] + If[[depth] > [0]] + { + next text, chunk, delim <- [text]Get DString[("/*","*/")] {} {} {} + { + next text <- "" + delim <- "" + } + If[[delim] = ["/*"]] + { + next depth <- [depth] + [1] + }{ + next depth <- [depth] - [1] + } + If[[next depth] = [0]] + { + next comment <- [comment]Append[chunk] + }{ + next comment <- [[comment]Append[chunk]]Append[delim] + } + out <- Block Comment[next comment, [[raw comment]Append[chunk]]Append[delim], next depth, next text, simple tokens, token list] + }{ + out <- _Lex[text, [raw comment]Slice[0], simple tokens, [token list]Append[Token["Block Comment", raw comment, comment]]] + } +} + +Numeric Literal[literal, text, simple tokens, token list:out] +{ + first,rest <- [text]Slice[1] + If[[first] In ["01234567890.x"]] + { + out <- Numeric Literal[[literal]Append[first], rest, simple tokens, token list] + }{ + out <- _Lex[text, [first]Slice[0], simple tokens, [token list]Append[Token["Numeric Literal", literal, literal]]] + } +} + +Add Token[token, text, simple tokens, token list:out] +{ + out <- _Lex[text, [text]Slice[0], simple tokens, [token list]Append[token]] +} + +_Lex[text, symbol, simple tokens,token list:out] +{ + If[[[text]Length] > [0]] + { + first,rest <- [text]Slice[1] + [simple tokens]Index[To String[first]] + { + token worker <- [["Add Token"]Set Input[0, Token[~, first, ""]]]Set Input[1, rest] + }{ + If[[first] = ["\""]] + { + escapes <- [[[New@Dictionary[]]Set["n","\n"]]Set["r","\r"]]Set["t","\t"] + token worker <- [[[["String Literal"]Set Input[0, [first]Slice[0]]]Set Input[1, first]]Set Input[2, escapes]]Set Input[3, rest] + //out <- String Literal["", first, rest, simple tokens, token list, escapes] + }{ + second,second rest <- [rest]Slice[1] + If[[[first] = ["<"]] And [[second]=["-"]]] + { + [first]Append[second] + { + token worker <- [["Add Token"]Set Input[0, Token["Assignment", ~, ~]]]Set Input[1, second rest] + } + }{ + + If[[[first] = ["/"]] And [[second] = ["*"]]] + { + token worker <- [[[["Block Comment"]Set Input[0, [first]Slice[0]]]Set Input[1, [first]Append[second]]]Set Input[2, 1]]Set Input[3, second rest] + //out <- Block Comment[next text, simple tokens, token list, 1] + }{ + If[[[first] = ["/"]] And [[second] = ["/"]]] + { + token worker <- [["Line Comment"]Set Input[0, [first]Append[second]]]Set Input[1, second rest] + //out <- Line Comment["", [first]Append[second], next text, simple tokens, token list] + }{ + If[[[first]In["0123456789"]] Or [[[first] = ["-"]] And [[second]In["0123456789"]]]] + { + token worker <- [["Numeric Literal"]Set Input[0, first]]Set Input[1, rest] + //out <- Numeric Literal[text, simple tokens, token list] + }{ + out <- _Lex[rest, [symbol]Append[first], simple tokens, token list] + } + } + } + } + + } + } + Val[token worker] + { + trimmed <- Trim[symbol, " \t\r\n"] + If[[trimmed] = [""]] + { + next list <- Val[token list] + }{ + next list <- [token list]Append[Token["Symbol", trimmed, trimmed]] + } + out <- [[token worker]Do[ + [[()]Append[simple tokens]]Append[next list]] + ]Index[0] + } + }{ + out <- token list + } +} + +Lex[text:out] +{ + simple tokens <- [[[[[[[[[[[New@Dictionary[] + ]Set["{", "Block Begin"] + ]Set["}", "Block End"] + ]Set["(", "List Begin"] + ]Set[")", "List End"] + ]Set["[", "Args Begin"] + ]Set["]", "Args End"] + ]Set[",", "List Separator"] + ]Set[":", "Name Separator"] + ]Set["@", "Method Separator"] + ]Set["`", "Binary Operation"] + ]Set["\n", "Newline"] + out <- _Lex[text, [text]Slice[0], simple tokens, ()] +} diff -r b3f71490858c -r 73e978d590c7 nworker.rhope --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nworker.rhope Wed Apr 29 02:58:03 2009 -0400 @@ -0,0 +1,302 @@ +Import extendlib.rhope + +Blueprint Range +{ + Start + Stop +} + +Range[start,stop:out] +{ + out <- [[Build["Range"]]Start <<[start]]Stop <<[stop] +} + +First@Range[range:first,none] +{ + If[[[range]Start >>] < [[range]Stop >>]] + { + first <- [range]Start >> + }{ + none <- range + } +} + +Next@Range[range,current:next,none] +{ + pnext <- [current]+[1] + If[[pnext] < [[range]Stop >>]] + { + next <- Val[pnext] + }{ + none <- range + } +} + +Index@Range[range,index:val,none] +{ + val <- index +} + +Set@Range[range,index,val:out] +{ + out <- [[()]Concatenate[range] + ]Set[index,val] +} + +List of Lists[num:out] +{ + out <- Fold[["Append"]Set Input[1, ()],(), Range[0,num]] +} + +Blueprint Worker Ref +{ + Name + Convention + Inputs + Outputs +} + +Worker Ref[name,convention,inputs,outputs:out] +{ + out <- [[[[Build["Worker Ref"]]Name <<[name]]Convention <<[convention]]Inputs <<[inputs]]Outputs <<[outputs] +} + +Blueprint Node Ref +{ + Index + IO Num +} + +Node Ref[index,ionum:out] +{ + out <- [[Build["Node Ref"]]Index <<[index]]IO Num <<[ionum] +} + +=@Node Ref[left,right:out] +{ + ,out <- If[[[left]Index >>] = [[right]Index >>]] + { + out <- [[left]IO Num>>] = [[right]IO Num >>] + } +} + +Blueprint NWorker Node +{ + Type + Data + Inputs + Outputs + Wires From + Wires To +} + +Wire To@NWorker Node[node,from,output,input:out] +{ + out <- [node]Wires To <<[ + [[node]Wires To >>]Set[input, + [[[node]Wires To >>]Index[input] + ]Append[Node Ref[from,output]] + ] + ] +} + +Wire From@NWorker Node[node,to,input,output:out] +{ + out <- [node]Wires From <<[ + [[node]Wires From >>]Set[output, + [[[node]Wires From >>]Index[output] + ]Append[Node Ref[to,input]] + ] + ] +} + +_Dependency[dlist,ref:out] +{ + [dlist]Find[ref] + { + out <- dlist + }{ + out <- [dlist]Append[ref] + } +} + +Dependencies@NWorker Node[node:out] +{ + out <- Fold[["Fold"]Set Input[0, "_Dependency"], (), [node]Wires To >>] +} + + +NWorker Node[type,data,inputs,outputs:out] +{ + out <- [[[[[[Build["NWorker Node"] + ]Type <<[type] + ]Data <<[data] + ]Inputs <<[inputs] + ]Outputs <<[outputs] + ]Wires From <<[List of Lists[outputs]] + ]Wires To <<[List of Lists[inputs]] +} + +Blueprint NWorker +{ + Convention + Nodes + Inputs + Outputs +} + +NWorker[convention:out] +{ + out <- [[[[Build["NWorker"]]Convention <<[convention]]Nodes <<[()]]Inputs <<[()]]Outputs <<[()] +} + +Add Node@NWorker[worker,type,data,inputs,outputs:out,node index] +{ + out <- [worker]Nodes <<[[[worker]Nodes >>]Append[NWorker Node[type,data,inputs,outputs]]] + node index <- [[worker]Nodes >>]Length +} + +Add Worker Call@NWorker[worker,tocall:out,node index] +{ + out, node index <- [worker]Add Node["call",tocall,[tocall]Inputs >>,[tocall]Outputs >>] +} + +Add Constant@NWorker[worker,constant:out,node index] +{ + out, node index <- [worker]Add Node["const",constant,0,1] +} + +Add Input@NWorker[worker,name,number:out,node index] +{ + ,node index <- [worker]Add Node["input",number,0,1] + { out <- [~]Inputs <<[[[~]Inputs >>]Set[number,name]] } +} + +Add Output@NWorker[worker,name,number:out,node index] +{ + ,node index <- [worker]Add Node["output",number,1,0] + { out <- [~]Outputs <<[[[~]Outputs >>]Set[number,name]] } +} + +Add Wire@NWorker[worker,from,output,to,input:out] +{ + fromw <- [[[worker]Nodes >>]Index[from]]Wire From[to,input,output] + tow <- [[[worker]Nodes >>]Index[to]]Wire To[from,output,input] + nodes <- [[[worker]Nodes >>]Set[from, fromw]]Set[to, tow] + out <- [worker]Nodes <<[nodes] +} + +_No Dependencies[list,node,index:out] +{ + [[node]Wires To>>]First + { + out <- Val[list] + }{ + out <- [list]Append[index] + } +} + +No Dependencies@NWorker[worker:out] +{ + out <- Fold["_No Dependencies", (), [worker]Nodes >>] +} + +_Collect Dests[candidates,wire:out] +{ + out <- [candidates]Set[[wire]Index >>, Yes] +} + +Collect Dests@NWorker[worker,candidates,node index:out] +{ + out <- Fold[["Fold"]Set Input[0, "_Collect Dests"], candidates, [[[worker]Nodes >>]Index[node index]]Wires From >>] +} + +Check Dependency@NWorker[worker,nodes,wires,wire index:met?] +{ + ref <- [wires]Index[wire index] + [nodes]Find[[ref]Index >>] + { + [wires]Next[wire index] + { + met? <- [worker]Check Dependency[nodes,wires,~] + }{ + met? <- Yes + } + }{ + Print[[ref]Index >>] + met? <- No + } +} +_Check Dependencies@NWorker[worker,nodes,inputs,input index:met?] +{ + wires <- [inputs]Index[input index] + [wires]First + { + current met? <- [worker]Check Dependency[nodes, wires, ~] + }{ + current met? <- Yes + } + If[current met?] + { + [inputs]Next[input index] + { + met? <- [worker]_Check Dependencies[nodes,inputs,~] + }{ + met? <- Yes + } + }{ + met? <- No + } +} + +Check Dependencies@NWorker[worker,nodes,candidate:met?] +{ + inputs <- [[[worker]Nodes >>]Index[candidate]]Wires To >> + [inputs]First + { + met? <- [worker]_Check Dependencies[nodes, inputs, ~] + }{ + met? <- Yes + } +} + +Dependants@NWorker[worker,direct nodes,nodes:out] +{ + candidates <- Keys[Fold[["Collect Dests"]Set Input[0,worker], (), direct nodes]] + out <- Filter[candidates, [["Check Dependencies"]Set Input[0, worker]]Set Input[1, nodes]] +} + +_Dependency Groups@NWorker[worker,last,all,grouped:out] +{ + current <- [worker]Dependants[last,all] + [current]First + { + out <- [worker]_Dependency Groups[current, [all]Concatenate[current], [grouped]Append[current]] + }{ + out <- grouped + } +} +Dependency Groups@NWorker[worker:out] +{ + no deps <- [worker]No Dependencies + out <- [worker]_Dependency Groups[no deps, no deps, [()]Append[no deps]] +} + +Test[:out] +{ + ref+ <- Worker Ref["+","cdecl",2,1] + ref* <- Worker Ref["*","cdecl",2,1] + ,a <- [NWorker["cdecl"] + ]Add Input["a", 0] { + ,b <- [~]Add Input["b", 1] { + ,c <- [~]Add Input["c", 2] { + ,outref <- [~]Add Output["out", 0] { + ,call+ <- [~]Add Worker Call[ref+] { + ,call* <- [~]Add Worker Call[ref*] { + out <- [[[[[~]Add Wire[a,0,call+,0] + ]Add Wire[b,0,call+,1] + ]Add Wire[call+,0,call*,0] + ]Add Wire[c,0,call*,1] + ]Add Wire[call*,0,outref,0] + }}}}}} +} \ No newline at end of file diff -r b3f71490858c -r 73e978d590c7 parse.rhope --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/parse.rhope Wed Apr 29 02:58:03 2009 -0400 @@ -0,0 +1,326 @@ + +Blueprint Error +{ + Message + Line + Column +} + +Error[msg,text:out] +{ + out <- [[[Build["Error"]]Message <<[msg]]Line << [ [[text]Line >>]+[1] ]]Column << [ [[text]Column >>]+[1] ] +} + +To String@Error[error:out] +{ + out <- [[[[[error]Message >>]Append[" on line "]]Append[[error]Line >>]]Append[" at column "]]Append[[error]Column >>] +} + +Blueprint PImport Node +{ + File +} + +PImport Node[file:out] +{ + out <- [Build["PImport Node"]]File <<[file] +} + +Blueprint Worker Node +{ + Name + Blueprint + Inputs + Outputs + Tree +} + +Add Node Input@Worker Node[node,input:out] +{ + Print["Add Node Input"] + Print[["Input: "]Append[To String[input]]] + out <- [node]Inputs <<[[[node]Inputs >>]Append[input]] +} + +Add Node Output@Worker Node[node,output:out] +{ + out <- [node]Outputs <<[[[node]Outputs >>]Append[output]] +} + +Body[node,tokens,current,depth:out,out index, done] +{ + Print[["Body: Depth="]Append[depth]] + If[[depth] > [0]] + { + token <- [tokens]Index[current] + [token]Type Match["Block Begin"] + { + ,end stream <- [tokens]Next[current] + { + out,out index, done <- Body[node,tokens,~,[depth]+[1]] + } + }{ + [token]Type Match["Block End"] + { + [tokens]Next[current] + { + out,out index, done <- Body[node,tokens,~,[depth]-[1]] + }{ + ,end stream <- If[[depth] = [1]] + { + Print["done"] + out <- Val[node] + done <- Yes + } + } + }{ + ,end stream <- [tokens]Next[current] + { + out,out index, done <- Body[node,tokens,~,depth] + } + } + } + }{ + out <- node + out index <- current + } + Val[end stream] + { + Print[To String[Error[["Unexpected end of stream after token of type "]Append[[token]Type >>], [token]Raw Text >>]]] + } +} + +Before Body[node,tokens,current:out,out index, done] +{ + Print["Before body"] + token <- [tokens]Index[current] + next,end stream <- [tokens]Next[current] + { + [token]Type Match["Block Begin"] + { + out,out index, done <- Body[node,tokens,next,1] + }{ + out,out index, done <- Before Body[node,tokens,next] + } + } + Val[end stream] + { + Print[To String[Error[["Unexpected end of stream after token of type "]Append[[token]Type >>], [token]Raw Text >>]]] + } +} + +Outputs[node,tokens,current:out,out index, done] +{ + Print["outputs"] + token <- [tokens]Index[current] + next,end stream <- [tokens]Next[current] + { + [token]Type Match["Symbol"] + { + out,out index, done <- Outputs[[node]Add Node Output[[token]Text >>], tokens, next] + }{ + [token]Type Match["Args End"] + { + out,out index, done <- Before Body[node, tokens, next] + }{ + [token]Type Match[("List Separator","Block Comment","Line Comment","Newline")] + { + out,out index, done <- Outputs[node, tokens, next] + }{ + Print[To String[Error[["Unexpected token of type "]Append[[token]Type >>], [token]Raw Text >>]]] + } + } + } + } + Val[end stream] + { + Print[To String[Error[["Unexpected end of stream after token of type "]Append[[token]Type >>], [token]Raw Text >>]]] + } +} + +Inputs[node,tokens,current:out,out index, done] +{ + Print["Inputs"] + token <- [tokens]Index[current] + next,end stream <- [tokens]Next[current] + { + [token]Type Match["Symbol"] + { + + out,out index, done <- Inputs[[node]Add Node Input[[token]Text >>], tokens, next] + }{ + [token]Type Match["Name Separator"] + { + Print["in out sep"] + out,out index, done <- Outputs[node, tokens, next] + }{ + [token]Type Match["Args End"] + { + out,out index, done <- Before Body[node, tokens, next] + }{ + [token]Type Match[("List Separator","Block Comment","Line Comment","Newline")] + { + out,out index,done <- Inputs[node, tokens, next] + }{ + Print[To String[Error[["Unexpected token of type "]Append[[token]Type >>], [token]Raw Text >>]]] + } + } + } + } + } + Val[end stream] + { + Print[To String[Error[["Unexpected end of stream after token of type "]Append[[token]Type >>], [token]Raw Text >>]]] + } +} + +Method[node,tokens,current:out,out index,done] +{ + token <- [tokens]Index[current] + next <- [tokens]Next[current] + { + [token]Type Match["Symbol"] + { + out,out index,done <- Before Inputs[[node]Blueprint <<[[token]Text >>], tokens, next] + }{ + [token]Type Match[("List Separator","Block Comment","Line Comment","Newline")] + { + out,out index,done <- Method[node, tokens, next] + }{ + Print[To String[Error[["Unexpected token of type "]Append[[token]Type >>], [token]Raw Text >>]]] + } + } + }{ + Print[To String[Error[["Unexpected end of stream after token of type "]Append[[token]Type >>], [token]Raw Text >>]]] + } +} + +//TODO: support method declarations +Before Inputs[node, tokens, current:out, out index, done] +{ + Print["Before Inputs"] + token <- [tokens]Index[current] + [token]Type Match["Args Begin"] + { + [tokens]Next[current] + { + out,out index, done <- Inputs[node, tokens, ~] + }{ + Print[To String[Error[["Unexpected end of stream after token of type "]Append[[token]Type >>], [token]Raw Text >>]]] + } + }{ + [token]Type Match["Method Separator"] + { + [tokens]Next[current] + { + out,out index,done <- Method[node, tokens, ~] + }{ + Print[To String[Error[["Unexpected end of stream after token of type "]Append[[token]Type >>], [token]Raw Text >>]]] + } + }{ + [token]Type Match[("Line Comment","Block Comment","Newline")] + { + continue <- Yes + }{ + Print[To String[Error[["Unexpected token of type "]Append[[token]Type >>], [token]Raw Text >>]]] + } + Val[continue] + { + [tokens]Next[current] + { + out,out index, done <- Before Inputs[node, tokens, ~] + }{ + Print[To String[Error[["Unexpected end of stream after token of type "]Append[[token]Type >>], [token]Raw Text >>]]] + } + } + } + } +} + +Worker Node[name, tokens, current:out,out index, done] +{ + Print[["Worker: "]Append[To String[name]]] + out,out index, done <- Before Inputs[[[[[Build["Worker Node"]]Name <<[name]]Inputs <<[()]]Outputs <<[()]]Tree <<[()], tokens, current] +} + +Blueprint PBlueprint Node +{ + Name + Fields +} + +PBlueprint Node[name, tokens, current:out,out index,done] +{ + out <- [[Build["PBlueprint Node"]]Name <<[name]]Fields <<[()] + out index <- current + //TODO: Parse rest of blueprint definition +} + + +Top Level[tokens, current, nodes:out] +{ + token <- [tokens]Index[current] + Print[[token]Type >>] + [token]Type Match["Symbol"] + { + [[token]Text >>]After["Import "] + { + next nodes <- [nodes]Append[PImport Node[~]] + next index <- Val[current] + }{ + blueprint name,worker name <- [~]After["Blueprint "] + { + [tokens]Next[current] + { + , next index <- PBlueprint Node[blueprint name, tokens, ~] + { + next nodes <- [nodes]Append[~] + } {} { + Print["done!"] + out <- Val[next nodes] + } + }{ + Print[To String[Error[["Unexpected end of stream after symbol "]Append[[token]Text >>], [token]Raw Text >>]]] + } + }{ + [tokens]Next[current] + { + , next index <- Worker Node[worker name, tokens, ~] + { + next nodes <- [nodes]Append[~] + } {} { + Print["done!"] + out <- Val[next nodes] + } + }{ + Print[To String[Error[["Unexpected end of stream after symbol "]Append[[token]Text >>], [token]Raw Text >>]]] + } + } + } + + }{ + [token]Type Match[("Newline","Block Comment","Line Comment")] + { + next nodes <- Val[nodes] + next index <- Val[current] + }{ + Print[To String[Error[["Unexpected token of type "]Append[[token]Type >>], [token]Raw Text >>]]] + } + } + [tokens]Next[next index] + { + out <- Top Level[tokens, ~, next nodes] + }{ + out <- Val[next nodes] + } +} + +Parse[tokens:out] +{ + [tokens]First + { + out <- Top Level[tokens, ~, ()] + }{ + out <- () + } +}