diff --git a/build/strings/en/documentation.json b/build/strings/en/documentation.json index 323b409..79af43c 100644 --- a/build/strings/en/documentation.json +++ b/build/strings/en/documentation.json @@ -166,7 +166,13 @@ "Stack_GetCount": "Gets the count of items in the specified stack.", "Stack_GetCount_StackName": "The name of the stack.", "Stack_PopValue": "Pops a value from the specified stack.", - "Stack_PopValue_StackName": "The name of the stack.", + "Stack_PopValue_StackName": "The name of the stack.", + "Text": "The Text object provides helpful operations for working with Text.", + "Text_Append": "Appends two text inputs and returns the result as another text. This operation is particularly useful when dealing with unknown text in variables which could accidentally be treated as numbers and get added, instead of getting appended.", + "Text_Append_Text1" : "First part of the text to be appended.", + "Text_Append_Text2" : "Second part of the text to be appended.", + "Text_GetLength" : "Gets the length of the given text.", + "Text_GetLength_Text" : "The text whose length is needed.", "TextWindow": "The TextWindow provides text-related input and output functionalities. For example using this class, it is possible to write or read some text or number to and from the text-based text window.", "TextWindow_Read": "Reads a line of text from the text window. Returns the string entered by the user.", "TextWindow_ReadNumber": "Reads a number from the text window. Returns the number entered by the user.", diff --git a/src/compiler/runtime/libraries-metadata.ts b/src/compiler/runtime/libraries-metadata.ts index e2583eb..fd92810 100644 --- a/src/compiler/runtime/libraries-metadata.ts +++ b/src/compiler/runtime/libraries-metadata.ts @@ -200,6 +200,18 @@ export class LibrariesMetadata { // No Events }); + public readonly Text: TypeMetadata = new TypeMetadata("Text", + { + Append: new MethodMetadata("Text", "Append", true, ["Text1", "Text2"]), + GetLength: new MethodMetadata("Text", "GetLength", true, ["Text"]) + }, + { + // No Properties + }, + { + // No Events + }); + public readonly TextWindow: TypeMetadata = new TypeMetadata("TextWindow", { Read: new MethodMetadata("TextWindow", "Read", true, []), diff --git a/src/compiler/runtime/libraries.ts b/src/compiler/runtime/libraries.ts index 62d7b58..4cc6fa3 100644 --- a/src/compiler/runtime/libraries.ts +++ b/src/compiler/runtime/libraries.ts @@ -9,6 +9,7 @@ import { LibrariesMetadata } from "./libraries-metadata"; import { MathLibrary } from "./libraries/math"; import { CompilerRange } from "../syntax/ranges"; import { ShapesLibrary } from "./libraries/shapes"; +import { TextLibrary } from "./libraries/text"; export interface LibraryTypeInstance { readonly methods: { readonly [name: string]: LibraryMethodInstance }; @@ -42,6 +43,7 @@ export class RuntimeLibraries { public readonly Program: ProgramLibrary = new ProgramLibrary(); public readonly Shapes: ShapesLibrary = new ShapesLibrary(); public readonly Stack: StackLibrary = new StackLibrary(); + public readonly Text: TextLibrary = new TextLibrary(); public readonly TextWindow: TextWindowLibrary = new TextWindowLibrary(); // TODO: public readonly Turtle: TurtleLibrary = new TurtleLibrary(); } diff --git a/src/compiler/runtime/libraries/text.ts b/src/compiler/runtime/libraries/text.ts new file mode 100644 index 0000000..9d71d72 --- /dev/null +++ b/src/compiler/runtime/libraries/text.ts @@ -0,0 +1,26 @@ +import { StringValue } from "../values/string-value"; +import { NumberValue } from "../values/number-value"; +import { ExecutionEngine } from "../../execution-engine"; +import { LibraryMethodInstance, LibraryTypeInstance, LibraryPropertyInstance, LibraryEventInstance } from "../libraries"; + +export class TextLibrary implements LibraryTypeInstance { + private executeAppend(engine: ExecutionEngine): void { + const text2 = engine.popEvaluationStack(); + const text1 = engine.popEvaluationStack(); + engine.pushEvaluationStack(new StringValue(text1.toValueString() + text2.toValueString())); + } + + private executeGetLength(engine: ExecutionEngine): void { + const text = engine.popEvaluationStack(); + engine.pushEvaluationStack(new NumberValue(text.toValueString().length)); + } + + public readonly methods: { readonly [name: string]: LibraryMethodInstance } = { + Append: { execute: this.executeAppend.bind(this) }, + GetLength: { execute: this.executeGetLength.bind(this) } + }; + + public readonly properties: { readonly [name: string]: LibraryPropertyInstance } = {}; + + public readonly events: { readonly [name: string]: LibraryEventInstance } = {}; +} diff --git a/src/strings/documentation.ts b/src/strings/documentation.ts index dfc5cd5..41ef151 100644 --- a/src/strings/documentation.ts +++ b/src/strings/documentation.ts @@ -169,6 +169,12 @@ export module DocumentationResources { export const Stack_GetCount_StackName = "The name of the stack."; export const Stack_PopValue = "Pops a value from the specified stack."; export const Stack_PopValue_StackName = "The name of the stack."; + export const Text = "The Text object provides helpful operations for working with Text."; + export const Text_Append = "Appends two text inputs and returns the result as another text. This operation is particularly useful when dealing with unknown text in variables which could accidentally be treated as numbers and get added, instead of getting appended."; + export const Text_Append_Text1 = "First part of the text to be appended."; + export const Text_Append_Text2 = "Second part of the text to be appended."; + export const Text_GetLength = "Gets the length of the given text."; + export const Text_GetLength_Text = "The text whose length is needed."; export const TextWindow = "The TextWindow provides text-related input and output functionalities. For example using this class, it is possible to write or read some text or number to and from the text-based text window."; export const TextWindow_Read = "Reads a line of text from the text window. Returns the string entered by the user."; export const TextWindow_ReadNumber = "Reads a number from the text window. Returns the number entered by the user."; diff --git a/tests/compiler/runtime/libraries/text.ts b/tests/compiler/runtime/libraries/text.ts new file mode 100644 index 0000000..cda3a30 --- /dev/null +++ b/tests/compiler/runtime/libraries/text.ts @@ -0,0 +1,36 @@ +import "jasmine"; +import { verifyRuntimeResult } from "../../helpers"; + +describe("Compiler.Runtime.Libraries.Text", () => { + it("can return appended text", () => { + verifyRuntimeResult(` +x = 1 +y = "value" +TextWindow.WriteLine(Text.Append(x, y)) +TextWindow.WriteLine(Text.Append(x, "test"))`, + [], + [ + "1value", + "1test" + ]); + }); + + it("can can get length of the string", () => { + verifyRuntimeResult(` +str1 = "" +str2 = "test" +TextWindow.WriteLine(Text.GetLength(0)) +TextWindow.WriteLine(Text.GetLength("a")) +TextWindow.WriteLine(Text.GetLength(x)) ' Nothing +TextWindow.WriteLine(Text.GetLength(str1)) +TextWindow.WriteLine(Text.GetLength(str2))`, + [], + [ + "1", + "1", + "0", + "0", + "4" + ]); + }); +}); diff --git a/tests/compiler/tests-list.ts b/tests/compiler/tests-list.ts index dcd909f..653f208 100644 --- a/tests/compiler/tests-list.ts +++ b/tests/compiler/tests-list.ts @@ -28,6 +28,7 @@ import "./runtime/libraries/clock"; import "./runtime/libraries/math"; import "./runtime/libraries/program"; import "./runtime/libraries/stack"; +import "./runtime/libraries/text"; import "./runtime/libraries/text-window"; import "./runtime/statements/for-loop";