Skip to content

Commit

Permalink
add first & last virtual opcodes
Browse files Browse the repository at this point in the history
  • Loading branch information
MichalMarsalek committed Mar 12, 2024
1 parent 4a2c96d commit ba06617
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 7 deletions.
128 changes: 128 additions & 0 deletions src/IR/opcodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,21 @@ export const opCodeDefinitions = {
"at[Array]": { args: [array(T1, T2), T2], front: "@" },
"at[List]": { args: [list(T1), int(0)], front: "@" },
"at_back[List]": { args: [list(T1), int("-oo", -1)], front: "@" },
"first[List]": { args: [list(T1)] },
"last[List]": { args: [list(T1)] },
"at[Table]": { args: [table(T1, T2), T1], front: "@" },
"at[Ascii]": { args: [ascii, int(0)], front: "@" },
"at_back[Ascii]": { args: [ascii, int("-oo", -1)], front: "@" },
"first[Ascii]": { args: [ascii] },
"last[Ascii]": { args: [ascii] },
"at[byte]": { args: [text(), int(0)], front: true },
"at_back[byte]": { args: [text(), int("-oo", -1)], front: true },
"first[byte]": { args: [text()] },
"last[byte]": { args: [text()] },
"at[codepoint]": { args: [text(), int(0)], front: true },
"at_back[codepoint]": { args: [text(), int("-oo", -1)], front: true },
"first[codepoint]": { args: [text()] },
"last[codepoint]": { args: [text()] },
"with_at[Array]": { args: [array(T1, T2), T2, T1], front: "@" },
"with_at[List]": { args: [list(T1), int(0), T1], front: "@" },
"with_at_back[List]": { args: [list(T1), int("-oo", -1), T1], front: "@" },
Expand Down Expand Up @@ -258,6 +266,14 @@ export const VirtualOpCodes = [
"ord_at_back[byte]",
"ord_at_back[codepoint]",
"ord_at_back[Ascii]",
"first[Ascii]",
"first[byte]",
"first[codepoint]",
"first[List]",
"last[Ascii]",
"last[byte]",
"last[codepoint]",
"last[List]",
] as const satisfies readonly AnyOpCode[];
export type VirtualOpCode = (typeof VirtualOpCodes)[number];

Expand Down Expand Up @@ -596,6 +612,110 @@ export const virtualOpCodeDefinitions = {
}
},
},
"first[List]": {
construct(data) {
return op["at[List]"](data, intNode(0));
},
getArgs(node) {
if (isOp["at[List]"](node) && isInt(0n)(node.args[1])) {
return [node.args[0]];
}
},
},
"first[Ascii]": {
construct(data) {
return op["at[Ascii]"](data, intNode(0));
},
getArgs(node) {
if (
isOp["at[List]"](node) &&
isInt(0n)(node.args[1]) &&
isOp["text_to_list[Ascii]"](node.args[0])
) {
return [node.args[0].args[0]];
}
},
},
"first[byte]": {
construct(data) {
return op["at[byte]"](data, intNode(0));
},
getArgs(node) {
if (
isOp["at[List]"](node) &&
isInt(0n)(node.args[1]) &&
isOp["text_to_list[byte]"](node.args[0])
) {
return [node.args[0].args[0]];
}
},
},
"first[codepoint]": {
construct(data) {
return op["at[codepoint]"](data, intNode(0));
},
getArgs(node) {
if (
isOp["at[List]"](node) &&
isInt(0n)(node.args[1]) &&
isOp["text_to_list[codepoint]"](node.args[0])
) {
return [node.args[0].args[0]];
}
},
},
"last[List]": {
construct(data) {
return op["at_back[List]"](data, intNode(-1));
},
getArgs(node) {
if (isOp["at_back[List]"](node) && isInt(-1n)(node.args[1])) {
return [node.args[0]];
}
},
},
"last[Ascii]": {
construct(data) {
return op["at_back[Ascii]"](data, intNode(-1));
},
getArgs(node) {
if (
isOp["at_back[List]"](node) &&
isInt(-1n)(node.args[1]) &&
isOp["text_to_list[Ascii]"](node.args[0])
) {
return [node.args[0].args[0]];
}
},
},
"last[byte]": {
construct(data) {
return op["at_back[byte]"](data, intNode(-1));
},
getArgs(node) {
if (
isOp["at_back[List]"](node) &&
isInt(-1n)(node.args[1]) &&
isOp["text_to_list[byte]"](node.args[0])
) {
return [node.args[0].args[0]];
}
},
},
"last[codepoint]": {
construct(data) {
return op["at_back[codepoint]"](data, intNode(-1));
},
getArgs(node) {
if (
isOp["at_back[List]"](node) &&
isInt(-1n)(node.args[1]) &&
isOp["text_to_list[codepoint]"](node.args[0])
) {
return [node.args[0].args[0]];
}
},
},
} as const satisfies {
[T in VirtualOpCode]?: VirtualOpCodeDefinition<T>;
};
Expand Down Expand Up @@ -692,16 +812,24 @@ export const opCodeDescriptions: Record<AnyOpCode, string> = {
"at[Array]": "Gets the item at the 0-based index.",
"at[List]": "Gets the item at the 0-based index.",
"at_back[List]": "Gets the item at the -1-based backwards index.",
"first[List]": "Gets the first item.",
"last[List]": "Gets the last item.",
"at[Table]": "Gets the item at the key.",
"at[Ascii]": "Gets the character at the 0-based index.",
"at_back[Ascii]": "Gets the character at the -1-based backwards index.",
"first[Ascii]": "Gets the first char.",
"last[Ascii]": "Gets the last char.",
"at[byte]": "Gets the byte (as text) at the 0-based index (counting bytes).",
"at_back[byte]":
"Gets the byte (as text) at the -1-based backwards index (counting bytes).",
"first[byte]": "Gets the first byte.",
"last[byte]": "Gets the last byte.",
"at[codepoint]":
"Gets the codepoint (as text) at the 0-based index (counting codepoints).",
"at_back[codepoint]":
"Gets the codepoint (as text) at the -1-based backwards index (counting codepoints).",
"first[codepoint]": "Gets the first codepoint.",
"last[codepoint]": "Gets the last codepoint.",
"with_at[Array]":
"Returns an array with item at the given 0-based index replaced.",
"with_at[List]":
Expand Down
4 changes: 1 addition & 3 deletions src/languages/clojure/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import {
int,
op,
text,
isInt,
intToDecOpOrText,
} from "../../IR";
import {
Expand Down Expand Up @@ -89,8 +88,7 @@ const clojureLanguage: Language = {
required(
mapOps({
append: (a, b) => func("conj", func("vec", a), b),
"at_back[List]": (a, b) =>
isInt(-1n)(b) ? func("last", a) : undefined,
"last[List]": (a) => func("last", a),
pow: (a, b) => func("int", func("Math/pow", a, b)),
}),
mapOpsTo.builtin({
Expand Down
6 changes: 2 additions & 4 deletions src/languages/janet/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import {
op,
rangeIndexCall,
text,
isInt,
intToDecOpOrText,
isForEachChar,
} from "../../IR";
Expand Down Expand Up @@ -116,9 +115,8 @@ const janetLanguage: Language = {
"contains[Table]": (a, b) =>
op.not(func("nil?", op["at[Table]"](a, b))),
}),
mapOps({
"at_back[List]": (a, b) =>
isInt(-1n)(b) ? func("last", a) : undefined,
mapOpsTo.func({
"last[List]": "last",
}),
mapBackwardsIndexToForwards({
"at_back[Ascii]": "size[Ascii]",
Expand Down

0 comments on commit ba06617

Please sign in to comment.