Mercurial > repos > rhope
diff parser.vistxt @ 0:76568becd6d6
Rhope Alpha 2a source import
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 28 Apr 2009 23:06:07 +0000 |
parents | |
children | b3f71490858c |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/parser.vistxt Tue Apr 28 23:06:07 2009 +0000 @@ -0,0 +1,1320 @@ +Import extendlib.vistxt + + + +Company Parser +|: + Arg Begin + Arg End + Line Comment + Comment Begin + Comment End + Assign + Block Begin + Block End + Blueprint Type Delim + Empty Block + Binary Operator + String Begin + String End + String Escape + List Begin + List End + List Delim + In Out Delim + Do Worker + Index Begin + Index End + Previous + Block Val + Set Field + Get Field + Import + Blueprint + Global Separator + Uses + Hex Escape + Escape Map +:| + +New@Parser(0,1) +|: + out(0) <- [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[Build["Parser"] + ]Arg Begin << ["["] + ]Arg End <<["]"] + ]Line Comment <<["//"] + ]Comment Begin <<["/*"] + ]Comment End <<["*/"] + ]Assign <<["<-"] + ]Block Begin <<["{"] + ]Block End <<["}"] + ]Blueprint Type Delim <<[":"] + ]Empty Block <<[";"] + ]Binary Operator <<["`"] + ]String Begin <<["\""] + ]String End <<["\""] + ]String Escape <<["\\"] + ]List Begin <<["("] + ]List End <<[")"] + ]List Delim <<[","] + ]In Out Delim <<[":"] + ]Do Worker <<["$"] + ]Index Begin <<["("] + ]Index End <<[")"] + ]Previous <<["@"] + ]Set Field <<["<<"] + ]Get Field <<[">>"] + ]Import <<["Import"] + ]Blueprint <<["Blueprint"] + ]Global Separator <<["::"] + ]Hex Escape <<["x"] + ]Uses <<["uses"] + ]Escape Map <<[[[[New@Dictionary[]]Set["n","\n"]]Set["r","\r"]]Set["t","\t"]] +:| + +Company Output Reference +|: + Index + Output Number +:| + +New@Output Reference(2,1) +|: + out(0) <- [[Build["Output Reference"]]Index <<[index(0)]]Output Number <<[num(1)] +:| + +Add Pipe Reference(3,1) +|: + reflist <- [refs(0)]Index[name(1)] |::| + |: + reflist <- New@List[] + :| + out(0) <- [refs(0)]Set[name(1), [reflist]Append[reference(2)]] +:| + +Assignment Save Reference(5,1) +|: + [[parse worker(3)]Outputs >>]Find[assignment(1)] + |: + out(0) <- refs(0) + :||: + out(0) <- Add Pipe Reference[refs(0), assignment(1), New@Output Reference[index(4), output num(2)]] + :| +:| + +Company Parse Program +|: + Workers + Imports + Blueprints + Errors +:| + +New@Parse Program(0,1) +|: + out(0) <- [[[Build["Parse Program"] + ]Workers <<[New@Dictionary[]] + ]Imports <<[New@Dictionary[]] + ]Blueprints <<[New@Dictionary[]] +:| + +Company Blueprint Definition +|: + Name + Fields +:| + +New@Blueprint Definition(2,1) +|: + out(0) <- [[Build["Blueprint Definition"]]Name << [name(0)]]Fields <<[fields(1)] +:| + +Company Parse Worker +|: + Name + Inputs + Outputs + Line Number + Trees + Uses Stores +:| + +New@Parse Worker(4,1) +|: + out(0) <- [[[[[[Build["Parse Worker"]]Name <<[name(0)]]Inputs <<[inputs(1)]]Outputs <<[outputs(2)]]Line Number <<[line(3)]]Trees <<[New@List[]]]Uses Stores <<[New@List[]] +:| + +Company Worker Node +|: + Name + Params + Assignments + Blocks + Index +:| + +New@Worker Node(2,1) +|: + out(0) <- [[[[Build["Worker Node"]]Name <<[name(0)]]Params <<[params(1)]]Assignments <<[New@List[]]]Blocks <<[New@List[]] +:| + +Add List Helper(6,3) +|: + ,nextworker,nextrefs <- [[list(0)]Index[key(3)]]Add to Worker[worker(1), program(2), parse worker(4), refs(5)] + |: nextlist <- [list(0)]Set[key(3), ~] :| + [list(0)]Next[key(3)] + |: + list(0),worker(1),refs(2) <- Add List Helper[nextlist, nextworker, program(2), ~, parse worker(4), nextrefs] + :||: + list(0) <- Val[nextlist] + worker(1) <- Val[nextworker] + refs(2) <- Val[nextrefs] + :| +:| + +Add List to Worker(5,3) +|: + [list(0)]First + |: + list(0),worker(1),refs(2) <- Add List Helper[list(0), worker(1), program(2), ~, parse worker(3), refs(4)] + :||: + list(0) <- list(0) + worker(1) <- worker(1) + refs(2) <- refs(4) + :| +:| + +_Add Blocks to Worker(6,3) +|: + block, next worker, nextrefs <- Add List to Worker[[blocks(0)]Index[key(4)], worker(1), program(2), parse worker(3), refs(5)] + next blocks <- [blocks(0)]Set[key(4), block] + [blocks(0)]Next[key(4)] + |: + blocks(0),worker(1),refs(2) <- _Add Blocks to Worker[next blocks, next worker, program(2), parseworker(3), ~, nextrefs] + :||: + blocks(0) <- Val[next blocks] + worker(1) <- Val[next worker] + refs(2) <- Val[nextrefs] + :| +:| + +Add Blocks to Worker(5,3) +|: + [blocks(0)]First + |: + blocks(0), worker(1), refs(2) <- _Add Blocks to Worker[blocks(0), worker(1), program(2), parse worker(3), ~, refs(4)] + :||: + blocks(0) <- blocks(0) + worker(1) <- worker(1) + refs(2) <- refs(4) + :| +:| + +Add to Worker@Worker Node(5,3) +|: + [program(2)]Find Worker[[node(0)]Name >>] + |: + after worker <- [worker(1)]Add Worker Call[~] |::| + |: + assignment refs <- Fold[[["Assignment Save Reference"]Set Input[3, parse worker(3)]]Set Input[4, ~], refs(4), [node(0)]Assignments >>] + [node(0)]Index <<[~] + |: + params list, params worker, params refs <- Add List to Worker[[~]Params >>, after worker, program(2), parse worker(3), assignment refs] + block list, worker(1), refs(2) <- Add Blocks to Worker[[~]Blocks >>, params worker, program(2), parse worker(3), params refs] + node(0) <- [[~]Params <<[params list]]Blocks <<[block list] + :| + :| + :||: + Print[["Error: Could not find a worker named "]Append[[node(0)]Name >>]] + :| +:| + +Add Multi Wire(5,1) +|: + out(0) <- [worker(0)]Add Wire[[ref(1)]Index >>, [ref(1)]Output Number >>, end index(3), input num(4)] +:| + +Add Param Wire(7,1) +|: + param worker, start index, output num <- [param(1)]Add Wires[worker(0), blocks(4), parse worker(5), assignments(6)] |::| + |: + out(0) <- [param worker]Add Wire[start index, output num, end index(3), input num(2)] + :||::||: + out(0) <- Fold[[["Add Multi Wire"]Set Input[3, end index(3)]]Set Input[4, input num(2)], param worker, ~] + :| +:| + +_Add Block Wire(6,1) +|: + out(0) <- [node(1)]Add Wires[worker(0), blocks(3), parse worker(4), assignments(5)] +:| + +Add Block Wire(7,1) +|: + blocks <- [existing blocks(4)]Append[New@Output Reference[parent index(3), output num(2)]] + out(0) <- Fold[[[["_Add Block Wire"]Set Input[3, blocks]]Set Input[4, parse worker(5)]]Set Input[5, assignments(6)], worker(0), block nodes(1)] + //out(0) <- [param(1)]Add Wires[worker(0), blocks] +:| + +Assignments Add Wires(5,1) +|: + [[parse worker(3)]Outputs >>]Find[assignment(1)] + |: + ,output index <- [worker(0)]Add Output[assignment(1), ~] + |: + worker(0) <- [~]Add Wire[start index(4), output num(2), output index, 0] + :| + :||: + //Ugly hack alert! + If[[asignment(1)]Contains["::"]] + |: + parts <- [assignment(1)]Split["::"] + ,global index <- [worker(0)]Add Global Set[[parts]Index[0], [parts]Index[1]] + |: + worker(0) <- [~]Add Wire[start index(4), output num(2), global index, 0] + :| + :||: + worker(0) <- worker(0) + :| + :| +:| + +Has Block@Worker Node(1,2) +|: + out(0) <- Yes +:| + +_Has Block Params(2,1) +|: + param <- [param list(0)]Index[key(1)] + out(0) <- [param]Has Block |::| + |: + [param list(0)]Next[key(1)] + |: + out(0) <- _Has Block Params[param list(0), ~] + :||: + out(0) <- No + :| + :| + +:| + +Has Block Params(1,1) +|: + [param list(0)]First + |: + out(0) <- _Has Block Params[param list(0), ~] + :||: + out(0) <- No + :| +:| + +Add Wires@Worker Node(5,4) +|: + worker(0),index(1),num(2) <- Add Wires Worker or Field[node(0), worker(1), blocks(2), parse worker(3), assignments(4)] +:| + +Add Wires Worker or Field(5,4) +|: + Fold[[["Assignments Add Wires"]Set Input[3, parse worker(3)]]Set Input[4, [node(0)]Index >>], worker(1), [node(0)]Assignments >>] + |: Fold[[[[["Add Block Wire"]Set Input[3, [node(0)]Index >>]]Set Input[4, blocks(2)]]Set Input[5, parse worker(3)]]Set Input[6, assignments(4)], ~, [node(0)]Blocks >>] + |: params worker <- Fold[[[[["Add Param Wire"]Set Input[3, [node(0)]Index >>]]Set Input[4, blocks(2)]]Set Input[5, parse worker(3)]]Set Input[6, assignments(4)], ~, [node(0)]Params >>] :|:| + If[Has Block Params[[node(0)]Params >>]] + |: + worker(0) <- Val[params worker] + :||: + [blocks(2)]Peek + |: + worker(0) <- [params worker]Add Wire[[~]Index >>, [~]Output Number >>, [node(0)]Index >>, [0]-[1]] + :||: + worker(0) <- Val[params worker] + :| + :| + index(1) <- [node(0)]Index >> + num(2) <- 0 +:| + +Company Field Node +|: + Name + Params + Assignments + Blocks + Index + Set? +:| + +Has Block@Field Node(1,2) +|: + has block(0) <- Yes +:| + +New@Field Node(3,1) +|: + out(0) <- [[[[[Build["Field Node"]]Name <<[name(0)]]Assignments <<[New@List[]]]Blocks <<[New@List[]]]Set? <<[set(2)]]Params <<[params(1)] +:| + +Add to Worker@Field Node(5,3) +|: + If[[node(0)]Set? >>] + |: + after worker,index <- [worker(1)]Add Object Set[[node(0)]Name >>] + :||: + after worker,index <- [worker(1)]Add Object Get[[node(0)]Name >>] + :| + index + |: + assignment refs <- Fold[[["Assignment Save Reference"]Set Input[3, parse worker(3)]]Set Input[4, ~], refs(4), [node(0)]Assignments >>] + [node(0)]Index <<[~] + |: + params list, params worker, params refs <- Add List to Worker[[~]Params >>, after worker, program(2), parse worker(3), assignment refs] + block list, worker(1), refs(2) <- Add Blocks to Worker[[~]Blocks >>, params worker, program(2), parse worker(3), params refs] + node(0) <- [[~]Params <<[params list]]Blocks <<[block list] + :| + :| +:| + +Add Wires@Field Node(5,4) +|: + worker(0),index(1),num(2) <- Add Wires Worker or Field[node(0), worker(1), blocks(2), parse worker(3), assignments(4)] +:| + +Company Named Pipe Node +|: + Name + Assignments + Blocks + Index +:| + +Has Block@Named Pipe Node(1,2) +|: + If[[[node(0)]Index >>] < [0]] + |: + //~ should really be a parser parameter + If[[[node(0)]Name >>] = ["~"]] + |: + has block(0) <- Yes + :||: + no block(1) <- No + :| + :||: + has block(0) <- Yes + :| +:| + +New@Named Pipe Node(1,1) +|: + out(0) <- [[[Build["Named Pipe Node"]]Name <<[name(0)]]Assignments <<[New@List[]]]Blocks <<[New@List[]] +:| + +Add to Worker@Named Pipe Node(5,3) +|: + [[parse worker(3)]Inputs >>]Find[[node(0)]Name >>] + |: + after add <- [worker(1)]Add Input[[node(0)]Name >>, ~] |::| + |: + assign refs <- Fold[[["Assignment Save Reference"]Set Input[3, parse worker(3)]]Set Input[4, ~], refs(4), [node(0)]Assignments >>] + index node <- [node(0)]Index <<[~] + :| + :||: + after add <- worker(1) + index node <- [node(0)]Index <<[[0]-[1]] + //TODO: Handle assignments from a named pipe that isn't an input + assign refs <- refs(4) + :| + block list, worker(1), refs(2) <- Add Blocks to Worker[[node(0)]Blocks >>, after add, program(2), parse worker(3), assign refs] + node(0) <- [index node]Blocks <<[block list] +:| + +Add Wires@Named Pipe Node(5,4) +|: + reflist(3) <- [assignments(4)]Index[[node(0)]Name >>] + |: + //TODO: Fix support for a named pipe with a block + worker(0) <- worker (1) + :||: + If[[[node(0)]Name >>] = ["~"]] + |: + wires worker <- worker(1) + [blocks(2)]Peek + |: + my index <- [~]Index >> + num(2) <- [~]Output Number >> + :||: + //TODO: Propagate an error rather than printing it out + Print["Error, block reference symbol (~) located outside of a block"] + :| + :||: + If[[[node(0)]Index >>] < [0]] + |: + Print[[[["Error, reference to named pipe "]Append[[node(0)]Name >>]]Append[" that was never assigned to in worker "]]Append[[parse worker(3)]Name >>]] + :||: + my index <- [node(0)]Index >> + num(2) <- 0 + assignments worker <- Fold[[["Assignments Add Wires"]Set Input[3, parse worker(3)]]Set Input[4, [node(0)]Index >>], worker(1), [node(0)]Assignments >>] + [blocks(2)]Peek + |: + wires worker <- [assignments worker]Add Wire[[~]Index >>, [~]Output Number >>, [node(0)]Index >>, [0]-[1]] + :||: + wires worker <- Val[assignments worker] + :| + :| + :| + :| + index(1) <- my index + + worker(0) <- Fold[[[[["Add Block Wire"]Set Input[3, my index]]Set Input[4, blocks(2)]]Set Input[5, parse worker(3)]]Set Input[6, assignments(4)], wires worker, [node(0)]Blocks >>] +:| + +Company Global Node +|: + Store + Name + Assignments + Blocks + Index +:| + +New@Global Node(2,1) +|: + out(0) <- [[[[Build["Global Node"]]Store <<[store(0)]]Name <<[name(1)]]Assignments <<[New@List[]]]Blocks <<[New@List[]] +:| + +Add to Worker@Global Node(5,3) +|: + out worker(1) <- [worker(1)]Add Global Get[[node(0)]Store >>, [node(0)]Name >>] |::| + |: + refs(2) <- Fold[[["Assignment Save Reference"]Set Input[3, parse worker(3)]]Set Input[4, ~], refs(4), [node(0)]Assignments >>] + out node(0) <- [node(0)]Index <<[~] + :| + refs(2) <- refs(4) +:| + +Add Wires@Global Node(5,4) +|: + worker(0),index(1),num(2) <- Add Wires Literal or Global[node(0), worker(1), blocks(2), parse worker(3), assignments(4)] +:| + +Has Block@Global Node(1,2) +|: + out(0) <- Yes +:| + +Company Literal Node +|: + Value + Assignments + Blocks + Index +:| + +Has Block@Literal Node(1,2) +|: + out(0) <- Yes +:| + +New@Literal Node(1,1) +|: + out(0) <- [[[Build["Literal Node"]]Value <<[value(0)]]Assignments <<[New@List[]]]Blocks <<[New@List[]] +:| + +Add to Worker@Literal Node(5,3) +|: + out worker(1) <- [worker(1)]Add Constant[[node(0)]Value >>] |::| + |: + refs(2) <- Fold[[["Assignment Save Reference"]Set Input[3, parse worker(3)]]Set Input[4, ~], refs(4), [node(0)]Assignments >>] + out node(0) <- [node(0)]Index <<[~] + :| +:| + +Add Wires@Literal Node(5,4) +|: + worker(0),index(1),num(2) <- Add Wires Literal or Global[node(0), worker(1), blocks(2), parse worker(3), assignments(4)] +:| + +Add Wires Literal or Global(5,4) +|: + assignments worker <- Fold[[["Assignments Add Wires"]Set Input[3, parse worker(3)]]Set Input[4, [node(0)]Index >>], worker(1), [node(0)]Assignments >>] + [blocks(2)]Peek + |: + worker(0) <- [assignments worker]Add Wire[[~]Index >>, [~]Output Number>>, [node(0)]Index >>, [0]-[1]] + :||: + worker(0) <- Val[assignments worker] + :| + index(1) <- [node(0)]Index >> + num(2) <- 0 +:| + +Company Block Node +|: + Number +:| + +Company Parse Error +|: + Type + Text + Line Number +:| + +New@Parse Error(3,1) +|: + out(0) <- [[[Build["Parse Error"]]Type <<[type(0)]]Text <<[text(1)]]Line Number <<[number(2)] +:| + +Filter Empty(1,1) +|: + If[[[string(0)]Length] > [0]] + |: + out(0) <- Yes + :||: + out(0) <- No + :| +:| + +Company Blueprint Field +|: + Name + Type +:| + +New@Blueprint Field(2,1) +|: + out(0) <- [[Build["Blueprint Field"]]Name <<[name(0)]]Type <<[type(1)] +:| + +Process Blueprint Field(3,1) +|: + parts <- [field(1)]Split[delim(2)] + If[[[parts]Length] > [1]] + |: + out(0) <- [list(0)]Append[New@Blueprint Field[[parts]Index[1], [parts]Index[0]]] + :||: + out(0) <- [list(0)]Append[New@Blueprint Field[[parts]Index[0], "Any Type"]] + :| +:| + +Block Comment(4,1) +|: + If[[block count(3)] > [0]] + |: + after, before <- [string(0)]Get DString[[[New@List[]]Append[begin comment(1)]]Append[end comment(2)]] |::| |::| + |: + If[[~] = [begin comment(1)]] + |: + out(0) <- Block Comment[after, begin comment(1), end comment(2), [block count(3)]+[1]] + :||: + out(0) <- Block Comment[after, begin comment(1), end comment(2), [block count(3)]-[1]] + :| + :||: + //No match + out(0) <- "" + :| + :||: + out(0) <- string(0) + :| +:| + +Line Comment(1,1) +|: + [string(0)]Get DString["\n"] + |: + out(0) <- ["\n"]Append[~] + :| |::| |::| |: + out(0) <- "" + :| +:| + +_Get Comment DString(6,4) +|: + after,before,delim,nomatch(3) <- [string(0)]Get DString[delims(1)] + |: + If[[delim] = [line comment(2)]] + |: + after comment <- Line Comment[after] + :||: + If[[delim] = [begin comment(3)]] + |: + after comment <- Block Comment[after, begin comment(3), end comment(4), 1] + :||: + rest(0) <- Val[after] + before(1) <- [prev before(5)]Append[before] + delim(2) <- Val[delim] + :| + :| + :| |::| |::| |: + before(1) <- [prev before(5)]Append[before] + :| + + after comment + |: + rest(0),more before,delim(2),nomatch(3) <- _Get Comment DString[~, delims(1), line comment(2), begin comment(3), end comment(4), prev before(5)] + before(1) <- [before]Append[more before] + :| + +:| + +Get Comment DString(3,4) +|: + line comment <- [params(2)]Line Comment >> + begin comment <- [params(2)]Comment Begin >> + end comment <- [params(2)]Comment End >> + all delims <- [[[delims(1)]As List]Append[begin comment]]Append[line comment] + rest(0), before(1), delim(2), not found(3) <- _Get Comment DString[string(0), delims(1), line comment, begin comment, end comment, ""] +:| + +Comment Left Trim(3,1) +|: + line comment <- [params(2)]Line Comment >> + + end comment <- [params(2)]Comment End >> + trimmed <- Left Trim[string(0), trim chars(1)] + If[[trimmed]Starts With[line comment]] + |: + ,after delim <- [trimmed]Slice[[line comment]Length] + out(0) <- Comment Left Trim[Line Comment[after delim], trim chars(1), params(2)] + :||: + begin comment <- [params(2)]Comment Begin >> + If[[trimmed]Starts With[begin comment]] + |: + ,after delim <- [trimmed]Slice[[line comment]Length] + out(0) <- Comment Left Trim[Block Comment[after delim, begin comment, end comment, 1], trim chars(1), params(2)] + :||: + out(0) <- Val[trimmed] + :| + :| +:| + +Blueprint(4,1) +|: + ,whitespace name <- [string(0)]Get Comment DString[[params(1)]Block Begin >>, params(1)] + |: + ,no blueprint <- [whitespace name]Slice[ [[params(1)]Blueprint >>]Length ] + name <- Trim[no blueprint, "\r\n\t "] + name lines <- 0//[Count Substring[left, "\n"]] + [Count Substring[right, "\n"]] + ,body <- [~]Get Comment DString[ [params(1)]Block End >>, params(1)] + |: + body lines <- [body]Split["\n"] + more lines <- [[[body lines]Length] - [1]] + [name lines] + fields <- Fold[["Process Blueprint Field"]Set Input[2, [params(1)]Blueprint Type Delim >>], New@List[], Filter[Map[body lines, ["Trim"]Set Input[1,"\n\r\t "]], "Filter Empty"]] + new tree <- [tree(2)]Blueprints << [ [[tree(2)]Blueprints >>]Set[name, New@Blueprint Definition[name, fields]] ] + out(0) <- Null[~, params(1), new tree, [lines(3)] + [more lines]] + :| |::| |: + out(0) <- [tree(2)]Errors <<[ [[tree(2)]Errors >>]Append[New@Parse Error["Error",[["Blueprint is missing an block close symbol \""]Append[[params(1)]Block End >>]]Append["\""], lines(3)]] ] + :| + + :| |::| |: + out(0) <- [tree(2)]Errors <<[ [[tree(2)]Errors >>]Append[New@Parse Error["Error",[["Blueprint is missing an block open symbol \""]Append[[params(1)]Block Begin >>]]Append["\""], lines(3)]] ] + :| +:| + +Parse Import(4,1) +|: + [line]Slice[ [[params(1)]Import >>]Length ] |::| + |: + filename <- Trim[~, " \n\r\t"] + :| + new tree <- [tree(2)]Imports <<[ [[tree(2)]Imports >>]Set[filename, Yes] ] + ,line <- [string(0)]Get Comment DString["\n", params(1)] + |: + out(0) <- Null[~, params(1), new tree, [lines(3)] + [1]] + :| |::| |: + out(0) <- Val[new tree] + :| +:| + +Get Expression Blocks(3,2) +|: + check block <- Comment Left Trim[string(0), "\n\r\t ", params(1)] + If[[check block]Starts With[[params(1)]Block Begin >>]] + |: + ,begin block <- [check block]Slice[[[params(1)]Block Begin >>]Length] + trees, after block <- Worker Body[begin block, params(1), New@List[]] + blocks(0), after(1) <- Get Expression Blocks[after block, params(1), [blocks(2)]Append[trees]] + :||: + If[[check block]Starts With[[params(1)]Empty Block >>]] + |: + blocks(0) <- blocks(2) + ,after(1) <- [check block]Slice[[[params(1)]Empty Block >>]Length] + :||: + blocks(0) <- blocks(2) + after(1) <- Val[check block] + :| + :| +:| + +Parse Escape(2,2) +|: + code,rest <- [string(0)]Slice[1] + If[[code] = [[params(1)]Hex Escape >>]] + |: + hex,after(1) <- [rest]Slice[2] + char(0) <- [""]Put Byte[From Hex@Whole Number[hex]] + :||: + after(1) <- Val[rest] + char(0) <- [[params(1)]Escape Map >>]Index[code] |::| + |: + char(0) <- Val[code] + :| + :| +:| + +Parse String(3,2) +|: + delims <- [[New@List[]]Append[[params(1)]String End >>]]Append[[params(1)]String Escape >>] + after, before, delim <- [string(0)]Get Comment DString[delims, params(1)] + |: + If[[delim] = [[params(1)]String End >>]] + |: + value(0) <- [current(2)]Append[before] + after(1) <- Val[after] + :||: + char,after escape <- Parse Escape[after, params(1)] + value(0),after(1) <- Parse String[after escape, params(1), [[current(2)]Append[before]]Append[char]] + :| + :| +:| + +Parse List(3,2) +|: + trimmed <- Comment Left Trim[string(0), "\r\n\t ", params(1)] + If[[trimmed]Starts With[[params(1)]List End >>]] + |: + value(0) <- list(2) + ,after(1) <- [trimmed]Slice[[[params(1)]List End >>]Length] + :||: + If[[trimmed]Starts With[[params(1)]List Delim >>]] + |: + ,el string <- [trimmed]Slice[[[params(1)]List Delim >>]Length] + :||: + el string <- Val[trimmed] + :| + element,after el <- Named Pipe or Literal[el string, params(1)] + value(0),after(1) <- Parse List[after el, params(1), [list(2)]Append[[element]Get Value]] + :| +:| + +Get Value@Literal Node(1,1) +|: + out(0) <- [node(0)]Value >> +:| + +Get Value@Named Pipe Node(1,1) +|: + out(0) <- node(0) +:| + +Parse Number(2,2) +|: + delims <- [[[[{" ","\t","\n","\r"}]Append[[params(1)]List Delim >>]]Append[[params(1)]Block Begin >>]]Append[[params(1)]Arg End >>]]Append[[params(1)]List End >>] + after delim,valstring <- [string(0)]Get Comment DString[delims, params(1)] |::| |::| + |: + after(1) <- [~]Append[after delim] + :||: + after(1) <- "" + :| + first two,rest <- [valstring]Slice[2] + If[[first two] = ["0x"]] + |: + value(0) <- From Hex@Whole Number[rest] + :||: + If[[valstring]Contains["."]] + |: + value(0) <- <String@Real Number[valstring] + :||: + value(0) <- <String@Whole Number[valstring] + :| + :| +:| + +Named Pipe or Literal(2,2) +|: + name <- Comment Left Trim[string(0), "\n\r\t ", params(1)] + If[[name]Starts With[[params(1)]String Begin >>]] + |: + ,string begin <- [name]Slice[[[params(1)]String Begin >>]Length] + value,after(1) <- Parse String[string begin, params(1), ""] + :||: + If[[name]Starts With[[params(1)]List Begin >>]] + |: + ,list start <- [name]Slice[[[params(1)]List Begin >>]Length] + value,after(1) <- Parse List[list start, params(1), New@List[]] + :||: + If[[[name]Slice[1]]In["-0123456789"]] + |: + value,after(1) <- Parse Number[name, params(1)] + :||: + delims <- [[[[[[{"\n"}]Append[[params(1)]Block Begin >>]]Append[[params(1)]Block End >>]]Append[[params(1)]Empty Block >>]]Append[[params(1)]Arg End >>]]Append[[params(1)]List Delim >>]]Append[[params(1)]List End >>] + ,before,delim <- [name]Get Comment DString[delims, params(1)] + |: + after(1) <- [delim]Append[~] + :| |::| |::| |: + after(1) <- "" + :| + If[[before] = ["Yes"]] + |: + yesno <- Yes + :||: + If[[before] = ["No"]] + |: + yesno <- No + :||: + If[[before] = [""]] + |: + Print[[["Found "]Append[delim]]Append[" where a named pipe or literal was expected"]] + :||: + If[[before]Contains[[params(1)]Global Separator >>]] + |: + parts <- [before]Split[[params(1)]Global Separator >>] + out(0) <- New@Global Node[Right Trim[[parts]Index[0],"\r\n\t "], Trim[[parts]Index[1], "\r\n\t "]] + :||: + out(0) <- New@Named Pipe Node[Right Trim[before,"\r\n\t "]] + :| + :| + :| + :| + out(0) <- New@Literal Node[yesno] + :| + :| + :| + out(0) <- New@Literal Node[value] +:| + +Parse Arguments(3,2) +|: + args <- Comment Left Trim[string(0), "\r\n\t ", params(1)] + If[[args]Starts With[[params(1)]List Delim >>]] + |: + [args]Slice[[[params(1)]List Delim >>]Length] |::| + |: + final args <- Comment Left Trim[~, "\r\n\t ", params(1)] + :| + :||: + If[[args]Starts With[[params(1)]Arg End >>]] + |: + args(0) <- arglist(2) + ,after(1) <- [args]Slice[[[params(1)]Arg End >>]Length] + :||: + final args <- Val[args] + :| + :| + arg, after arg <- Parse Expression[final args, params(1)] + args(0), after(1) <- Parse Arguments[after arg, params(1), [arglist(2)]Append[arg]] +:| + +Worker or Field(3,1) +|: + get field <- [params(2)]Get Field >> + If[[name(0)]Ends With[get field]] + |: + field <- Right Trim[[name(0)]Slice[[[name(0)]Length] - [[get field]Length]], "\n\r\t "] + out(0) <- New@Field Node[field, args(1), No] + :||: + set field <- [params(2)]Set Field >> + If[[name(0)]Ends With[set field]] + |: + field <- Right Trim[[name(0)]Slice[[[name(0)]Length] - [[set field]Length]], "\n\r\t "] + out(0) <- New@Field Node[field, args(1), Yes] + :||: + out(0) <- New@Worker Node[name(0), args(1)] + :| + :| +:| + +Prefix(4,2) +|: + //Parse argument list + more args,after(1) <- Parse Arguments[string(0), params(1), existing args(3)] + expression(0) <- Worker or Field[name(2), more args, params(1)] +:| + +Postfix or Infix(2,2) +|: + args, after args <- Parse Arguments[string(0), params(1), New@List[]] + delims <- [[[[[{"\n"}]Append[[params(1)]Arg Begin >>]]Append[[params(1)]Empty Block >>]]Append[[params(1)]Block Begin >>]]Append[[params(1)]Arg End >>]]Append[[params(1)]List Delim >>] + after,before,delim <- [after args]Get Comment DString[delims, params(1)] + |: + If[[delim] = [[params(1)]Arg Begin >>]] + |: + expression(0), after(1) <- Prefix[after, params(1), Trim[before,"\r\n\t "], args] + :||: + If[[delim] = [[params(1)]Empty Block >>]] + |: + after expression(1) <- Val[after] + :||: + ,after expression(1) <- [after args]Slice[[before]Length] + :| + expression(0) <- Worker or Field[Trim[before,"\r\n\t "], args, params(1)] + :| + :| +:| + +Parse Expression(2,2) +|: + delims <- [[[[[[[{"\n"}]Append[[params(1)]Arg Begin >>]]Append[[params(1)]Arg End >>]]Append[[params(1)]Assign >>]]Append["\n"]]Append[[params(1)]Empty Block >>]]Append[[params(1)]Block End >>]]Append[[params(1)]String Begin >>] + after, before, delim <- [trimmed(0)]Get Comment DString[delims, params(1)] + |: + //If we find an arg begin token, we have a worker expression + If[[delim] = [[params(1)]Arg Begin >>]] + |: + maybe name <- Right Trim[before, "\r\t "] + //Prefix expressions will have the worker name before the first arg begin token + If[[maybe name] = [""]] + |: + expression, after expression <- Postfix or Infix[after, params(1)] + :||: + If[[maybe name]Contains[[params(1)]List Delim >>]] + |: + after expression <- [after literal]Append[[delim]Append[after]] + expression, after literal <- Named Pipe or Literal[Right Trim[before, "\r\n\t "], params(1)] + :||: + expression, after expression <- Prefix[after, params(1), maybe name, New@List[]] + :| + :| + :||: + If[[delim] = [[params(1)]Assign >>]] + |: + //Expressions starting with an assignment can be prefix, postfix or infix + //or they can be a simple literal or named pipe + assignments <- Map[[before]Split[[params(1)]List Delim >>], ["Trim"]Set Input[1,"\n\r\t "]] + ,after blocks(1) <- Parse Expression[Comment Left Trim[after, " \n\r\t", params(1)], params(1)] + |: + final expression(0) <- [~]Assignments <<[assignments] + :| + :||: + //If[[delim] = [[params(1)]String Begin >>]] + //|: + // If[[Trim[before, "\r\n\t "]] = [""]] + // |: + // expression, after expression <- Named Pipe or Literal[[delim]Append[after], params(1)] + // :||: + // after expression <- [after literal]Append[[delim]Append[after]] + // expression, after literal <- Named Pipe or Literal[Right Trim[before, "\r\n\t "], params(1)] + // :| + //:||: + // after expression <- [after literal]Append[[delim]Append[after]] + // expression, after literal <- Named Pipe or Literal[Right Trim[before, "\r\n\t "], params(1)] + //:| + expression, after expression <- Named Pipe or Literal[trimmed(0), params(1)] + :| + :| + //Any expression can be followed by one or more blocks mapping the inputs of other expressions + //to the outputs of the current one + blocks,after blocks(1) <- Get Expression Blocks[after expression, params(1), New@List[]] + final expression(0) <- [expression]Blocks <<[blocks] + :| +:| + +Worker Body(3,2) +|: + trimmed <- Comment Left Trim[string(0), "\n\r\t ", params(1)] + If[[trimmed]Starts With[[params(1)]Block End >>]] + |: + //We're done with this block, return + ,after end(1) <- [trimmed]Slice[[[params(1)]Block End >>]Length] + trees(0) <- trees(2) + :||: + expression, after expression <- Parse Expression[trimmed, params(1)] + trees(0),after end(1) <- Worker Body[after expression, params(1), [trees(2)]Append[expression]] + :| +:| + +Process Modifiers(3,1) +|: + //Eventually this will need to be more sophisticated to handle more modifiers + trimmed <- Comment Left Trim[modifiers(2), "\n\r\t ", params(1)] + If[[trimmed]Starts With[[params(1)]Uses >>]] + |: + ,after uses <- [trimmed]Slice[[[params(1)]Uses >>]Length] + ,stores string <- [after uses]Get Comment DString["\n", params(1)] + out(0) <- [worker(0)]Uses Stores <<[Map[[stores string]Split[[params(1)]List Delim >>], ["Trim"]Set Input[1, "\r\n\t "]]] + :||: + out(0) <- worker(0) + :| +:| + +Worker Name(4,1) +|: + ,whitespace name <- [string(0)]Get Comment DString[[params(1)]Arg Begin >>, params(1)] + |: + worker name <- Trim[whitespace name, "\n\r\t "] + in out <- [params(1)]In Out Delim >> + arg end <- [params(1)]Arg End >> + delims <- [[New@List[]]Append[in out]]Append[arg end] + after <- [~]Get Comment DString[delims, params(1)] |::| + |: + arglist <- Trim[~,"\r\n\t "] + :||: + //check if there is an in/out separator + //if it isn't present, everything in the arglist is an input + If[[~] = [in out]] + |: + after arglist <- [after]Get Comment DString[arg end, params(1)] |::| + |: + output string <- Trim[~,"\n\r\t "] + :| + :||: + after arglist <- Val[after] + output string <- "" + :| + inputs <- Map[[arglist]Split[[params(1)]List Delim >>], ["Trim"]Set Input[1,"\n\r\t "]] + outputs <- Map[[output string]Split[[params(1)]List Delim >>], ["Trim"]Set Input[1,"\n\r\t "]] + + New@Parse Worker[worker name, inputs, outputs, 0] + |: + body text, modifiers <- [after arglist]Get Comment DString[[params(1)]Block Begin >>, params(1)] + modified <- Process Modifiers[~, params(1), modifiers] + expression trees, after body <- Worker Body[body text, params(1), New@List[]] + worker <- [modified]Trees <<[expression trees] + new worker dict <- [[tree(2)]Workers >>]Set[worker name, worker] + out(0) <- Null[after body, params(1), [tree(2)]Workers <<[new worker dict], 0] + :| + :| + :||::||::||: + out(0) <- tree(2) + :| +:| + +Null(4,1) +|: + trimmed <- Comment Left Trim[string(0), " \n\r\t", params(1)] + current line <- 0//[lines(3)] + [Count Substring[whitespace, "\n"]] + If[[trimmed]Starts With[ [params(1)]Blueprint >> ]] + |: + out(0) <- Blueprint[trimmed, params(1), tree(2), current line] + :||: + If[[trimmed]Starts With[ [params(1)]Import >> ]] + |: + out(0) <- Parse Import[trimmed, params(1), tree(2), current line] + :||: + out(0) <- Worker Name[trimmed, params(1), tree(2), current line] + :| + :| +:| + +Add Workers(3,1) +|: + prog,worker <- [program(2)]New Worker[name(1)] + [worker]Set IO Counts[ [[[worker(0)]Index[name(1)]]Inputs >>]Length, [[[worker(0)]Index[name(1)]]Outputs >>]Length] + [workers(0)]Next[name(1)] + |: + out(0) <- Add Workers[workers(0), ~, prog] + :||: + out(0) <- Val[prog] + :| +:| + +Add Wires Helper(5,1) +|: + worker(0) <- [node(1)]Add Wires[worker(0), New@List[], parse worker(3), assignments(4)] +:| + +Add Contents(3,2) +|: + worker <- [[program(2)]Find Worker[name(1)]]Uses[[parse worker(0)]Uses Stores >>] + trees, contents worker, refs <- Add List to Worker[[parse worker(0)]Trees >>, worker, program(2), parse worker(0), New@Dictionary[]] + Fold[[["Add Wires Helper"]Set Input[3, parse worker(0)]]Set Input[4, refs], contents worker, trees] + out(0) <- [parse worker(0)]Trees <<[trees] + key(1) <- name(1) +:| + +Add Blueprint Field(3,1) +|: + out(0) <- [blueprint(0)]Add Field[[field(1)]Name >>, [field(1)]Type >>] +:| + +Add Blueprint(2,1) +|: + out(0) <- [prog(0)]New Blueprint[[def(1)]Name >>] |::| + |: + Fold["Add Blueprint Field", ~, [def(1)]Fields >>] + :| +:| + +_Tree to Program(2,1) +|: + after blueprint <- Fold["Add Blueprint", program(1), [parse tree(0)]Blueprints >>] + [[parse tree(0)]Workers >>]First + |: + prog <- Add Workers[[parse tree(0)]Workers >>, ~, after blueprint] + :| + Key Value Map[[parse tree(0)]Workers >>, ["Add Contents"]Set Input[2, prog]] + out(0) <- prog +:| + +Tree to Program(1,1) +|: + out(0) <- _Tree to Program[parse tree(0), [New@Program[]]Add Builtins] +:| + +Needs Imports(3,1) +|: + If[not imported?(1)] + |: + out(0) <- [needs import(0)]Append[name(2)] + :||: + out(0) <- needs import(0) + :| +:| + +Do Import(4,1) +|: + file <- <String@File[file name(1)] + ,text <- [file]Get FString[[file]Length] + after import <- Null[text, params(3), tree(0), 0] + out(0) <- [after import]Imports <<[ [[after import]Imports >>]Set[file name(1), No] ] +:| + +Process Imports(2,1) +|: + needs import <- Fold["Needs Imports", New@List[], [parse tree(0)]Imports >>] + If[[[needs import]Length] > [0]] + |: + import tree <- Fold[["Do Import"]Set Input[3, params(1)], parse tree(0), needs import] + out(0) <- Process Imports[import tree, params(1)] + :||: + out(0) <- parse tree(0) + :| +:| + +_Init Used Store(2,1) +|: + [dict(0)]Index[store name(1)] + |: + out(0) <- dict(0) + :||: + Init Store[store name(1)] + out(0) <- [dict(0)]Set[store name(1), Yes] + :| +:| + +_Init Used Stores(2,1) +|: + out(0) <- Fold["_Init Used Store", dict(0), [worker(1)]Uses Stores >>] +:| + +Init Used Stores(1,1) +|: + out(0) <- Fold["_Init Used Stores", existing stores(1), [parse tree(0)]Workers >>] +:| + +Until End(1,1) +|: + line <- Get Input[] + If[[line] = ["End"]] + |: + out(0) <- [text(0)]Append["\n"] + :||: + out(0) <- Until End[[[text(0)]Append["\n"]]Append[line]] + :| +:| + +_REPL(3,0) +|: + line <- Get Input[] + If[[line] = ["Begin"]] + |: + text <- Until End[""] + Null[text, params(0), New@Parse Program[], 0] + |: + define tree <- Process Imports[~, params(0)] + Init Used Stores[define tree, stores(2)] + |: _REPL[params(0), _Tree to Program[define tree, prog(1)], ~] :| + :| + :||: + If[[line]Starts With[[params(0)]Import >>]] + |: + Parse Import[[line]Append["\n"], params(0), New@Parse Program[], 0] + |: + import tree <- Process Imports[~, params(0)] + Init Used Stores[import tree, stores(2)] + |: _REPL[params(0), _Tree to Program[import tree, prog(1)], ~] :| + :| + :||: + trees <- Worker Body[[line]Append["}"], params(0), New@List[]] + tree <- [New@Worker Node["Val", [New@List[]]Append[[trees]Index[0]]]]Assignments <<[{"__out"}] + this stores <- [[tree]Gather Stores[params(0), New@Dictionary[]]]Keys + next stores <- Fold["_Init Used Store", stores(2), this stores] + |: + pworker <- [[New@Parse Worker["__Eval", New@List[], {"__out"}, 0]]Trees <<[[New@List[]]Append[tree]]]Uses Stores <<[this stores] + :| + [[prog(1)]Find Worker["__Eval"]]Clear + |: Add Contents[pworker, "__Eval", prog(1)] + |: Pretty Print[[[[prog(1)]Find Worker["__Eval"]]Do[New@List[]]]Index[0], ""] + |: _REPL[params(0), prog(1), next stores] :| :| :| + :| + :| +:| + +REPL(1,0) +|: + Print["Rhope Alpha 2\nCopyright 2008 by Michael Pavone\nEntering interactive mode\n"] + prog <- Tree to Program[Null["Val[in:out]\n{\n out <- in\n}\n__Eval[:__out]\n{\n}\n", params(0), New@Parse Program[], 0]] + _REPL[params(0), prog, New@Dictionary[]] +:| + +Add If Store(3,1) +|: + If[[name(1)]Contains[[params(2)]Global Separator >>]] + |: + parts <- [name(1)]Split[[params(2)]Global Separator >>] + out(0) <- [stores(0)]Set[[parts]Index[0], Yes] + :||: + out(0) <- stores(0) + :| +:| + +Param Gather Stores(3,1) +|: + out(0) <- [node(1)]Gather Stores[params(2), stores(0)] +:| + +Gather Stores@Named Pipe Node(3,1) +|: + out(0) <- Fold[["Add If Store"]Set Input[2, params(1)], stores(2), [node(0)]Assignments >>] +:| + +Gather Stores@Global Node(3,1) +|: + out(0) <- [stores(2)]Set[[node(0)]Store >>, Yes] +:| + +Gather Stores@Worker Node(3,1) +|: + //TODO: Handle blocks + store list <- Fold[["Param Gather Stores"]Set Input[2, params(1)], stores(2), [node(0)]Params >>] + out(0) <- Fold[["Add If Store"]Set Input[2, params(1)], store list, [node(0)]Assignments >>] +:| + +Gather Stores@Field Node(3,1) +|: + //TODO: Handle blocks + store list <- Fold[["Param Gather Stores"]Set Input[2, params(1)], stores(2), [node(0)]Params >>] + out(0) <- Fold[["Add If Store"]Set Input[2, params(1)], store list, [node(0)]Assignments >>] +:| + +Gather Stores@Literal Node(3,1) +|: + out(0) <- Fold[["Add If Store"]Set Input[2, params(1)], stores(2), [node(0)]Assignments >>] +:| + + +Main(1,0) +|: + + [args(0)]Index[1] + |: + file <- <String@File[~] + ,text <- [file]Get FString[[file]Length] + params <- New@Parser[] + Null[text, params, New@Parse Program[], 0] + |: + tree <- Process Imports[~, params] + Init Used Stores[tree, New@Dictionary[]] + |: [Tree to Program[tree]]Run[[args(0)]Tail[1]] :| + :| + :||: + REPL[New@Parser[]] + :| +:|