Implement basic integer math operations
This commit is contained in:
24
src/vm/commands/abs.ts
Normal file
24
src/vm/commands/abs.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import {Command} from "./command.js";
|
||||
import {LexInput} from "../lexer.js";
|
||||
import {StrVM} from "../vm.js";
|
||||
import {Awaitable} from "../../util/types.js";
|
||||
|
||||
export class Abs extends Command<{}> {
|
||||
attemptParse(): Awaitable<{}> {
|
||||
return {}
|
||||
}
|
||||
|
||||
getDisplayName(): string {
|
||||
return 'abs'
|
||||
}
|
||||
|
||||
isParseCandidate(token: LexInput): boolean {
|
||||
return this.isKeyword(token, 'abs')
|
||||
}
|
||||
|
||||
async execute(vm: StrVM): Promise<StrVM> {
|
||||
return vm.replaceContextMatchingTerm({
|
||||
int: sub => Math.abs(sub),
|
||||
})
|
||||
}
|
||||
}
|
||||
29
src/vm/commands/divide.ts
Normal file
29
src/vm/commands/divide.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import {Command, ParseContext, StrTerm} from "./command.js";
|
||||
import {LexInput} from "../lexer.js";
|
||||
import {StrVM} from "../vm.js";
|
||||
|
||||
export type DivideData = {
|
||||
val: StrTerm,
|
||||
}
|
||||
|
||||
export class Divide extends Command<DivideData> {
|
||||
async attemptParse(context: ParseContext): Promise<DivideData> {
|
||||
return {
|
||||
val: await context.popTerm(),
|
||||
}
|
||||
}
|
||||
|
||||
getDisplayName(): string {
|
||||
return 'divide'
|
||||
}
|
||||
|
||||
isParseCandidate(token: LexInput): boolean {
|
||||
return this.isKeyword(token, 'divide')
|
||||
}
|
||||
|
||||
async execute(vm: StrVM, data: DivideData): Promise<StrVM> {
|
||||
return vm.replaceContextMatchingTerm(ctx => ({
|
||||
int: sub => sub / ctx.resolveInt(data.val),
|
||||
}))
|
||||
}
|
||||
}
|
||||
@@ -60,9 +60,15 @@ import {Convert} from "./convert.js";
|
||||
import {While} from "./while.js";
|
||||
import {Table} from "./table.js";
|
||||
import {Push} from "./push.js";
|
||||
import {Plus} from "./plus.js";
|
||||
import {Minus} from "./minus.js";
|
||||
import {Times} from "./times.js";
|
||||
import {Divide} from "./divide.js";
|
||||
import {Abs} from "./abs.js";
|
||||
|
||||
export type Commands = Command<CommandData>[]
|
||||
export const commands: Commands = [
|
||||
new Abs,
|
||||
new Assign,
|
||||
new Call,
|
||||
new Chunk,
|
||||
@@ -71,6 +77,7 @@ export const commands: Commands = [
|
||||
new Contains,
|
||||
new Convert,
|
||||
new Copy,
|
||||
new Divide,
|
||||
new Drop,
|
||||
new Each,
|
||||
new Edit,
|
||||
@@ -91,11 +98,13 @@ export const commands: Commands = [
|
||||
new Load,
|
||||
new Lower,
|
||||
new LSub,
|
||||
new Minus,
|
||||
new Missing,
|
||||
new On,
|
||||
new OutFile,
|
||||
new Over,
|
||||
new Paste,
|
||||
new Plus,
|
||||
new Prefix,
|
||||
new Push,
|
||||
new Quote,
|
||||
@@ -113,6 +122,7 @@ export const commands: Commands = [
|
||||
new Suffix,
|
||||
new Table,
|
||||
new Take,
|
||||
new Times,
|
||||
new To,
|
||||
new Trim,
|
||||
new Undo,
|
||||
|
||||
29
src/vm/commands/minus.ts
Normal file
29
src/vm/commands/minus.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import {Command, ParseContext, StrTerm} from "./command.js";
|
||||
import {LexInput} from "../lexer.js";
|
||||
import {StrVM} from "../vm.js";
|
||||
|
||||
export type MinusData = {
|
||||
val: StrTerm,
|
||||
}
|
||||
|
||||
export class Minus extends Command<MinusData> {
|
||||
async attemptParse(context: ParseContext): Promise<MinusData> {
|
||||
return {
|
||||
val: await context.popTerm(),
|
||||
}
|
||||
}
|
||||
|
||||
getDisplayName(): string {
|
||||
return 'minus'
|
||||
}
|
||||
|
||||
isParseCandidate(token: LexInput): boolean {
|
||||
return this.isKeyword(token, 'minus')
|
||||
}
|
||||
|
||||
async execute(vm: StrVM, data: MinusData): Promise<StrVM> {
|
||||
return vm.replaceContextMatchingTerm(ctx => ({
|
||||
int: sub => sub - ctx.resolveInt(data.val),
|
||||
}))
|
||||
}
|
||||
}
|
||||
29
src/vm/commands/plus.ts
Normal file
29
src/vm/commands/plus.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import {Command, ParseContext, StrTerm} from "./command.js";
|
||||
import {LexInput} from "../lexer.js";
|
||||
import {StrVM} from "../vm.js";
|
||||
|
||||
export type PlusData = {
|
||||
val: StrTerm,
|
||||
}
|
||||
|
||||
export class Plus extends Command<PlusData> {
|
||||
async attemptParse(context: ParseContext): Promise<PlusData> {
|
||||
return {
|
||||
val: await context.popTerm(),
|
||||
}
|
||||
}
|
||||
|
||||
getDisplayName(): string {
|
||||
return 'plus'
|
||||
}
|
||||
|
||||
isParseCandidate(token: LexInput): boolean {
|
||||
return this.isKeyword(token, 'plus')
|
||||
}
|
||||
|
||||
async execute(vm: StrVM, data: PlusData): Promise<StrVM> {
|
||||
return vm.replaceContextMatchingTerm(ctx => ({
|
||||
int: sub => sub + ctx.resolveInt(data.val),
|
||||
}))
|
||||
}
|
||||
}
|
||||
29
src/vm/commands/times.ts
Normal file
29
src/vm/commands/times.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import {Command, ParseContext, StrTerm} from "./command.js";
|
||||
import {LexInput} from "../lexer.js";
|
||||
import {StrVM} from "../vm.js";
|
||||
|
||||
export type TimesData = {
|
||||
val: StrTerm,
|
||||
}
|
||||
|
||||
export class Times extends Command<TimesData> {
|
||||
async attemptParse(context: ParseContext): Promise<TimesData> {
|
||||
return {
|
||||
val: await context.popTerm(),
|
||||
}
|
||||
}
|
||||
|
||||
getDisplayName(): string {
|
||||
return 'times'
|
||||
}
|
||||
|
||||
isParseCandidate(token: LexInput): boolean {
|
||||
return this.isKeyword(token, 'times')
|
||||
}
|
||||
|
||||
async execute(vm: StrVM, data: TimesData): Promise<StrVM> {
|
||||
return vm.replaceContextMatchingTerm(ctx => ({
|
||||
int: sub => sub * ctx.resolveInt(data.val),
|
||||
}))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user