-
Argentum got string interpolation
05/18/2023 at 14:05 • 0 commentsresult = db.query("{} SELECT name, id FROM users WHERE name LIKE '{ encodeSql(request.userMask) }%' LIMIT {request.page * xPageSize}, {xPageSize}; "); request.mode == Json ? response.send(result.toJson()) : response.send("{} <ul>{ result.forRecords((record) { "{} <li data-id="{ record["id"] }"> { record["name"] } </li> "}) }</ul> ")
In this example we use string interpolation twice:
- to build an SQL query
- to convert query results to HTML
This SQL query is a simple multiline text string with { placeholders } . Placeholders are Argentum expressions that return everything convertible to strings.
HTML example demonstrates two nested interpolated strings - one for <ul> and one for nested <li>s.
More on string interpolation: here.
-
Argentum got raw multiline string literals
05/17/2023 at 20:20 • 0 comments// Program log(" Hello, I'm a multiline "raw" string "); // Prints: Hello, I'm a multiline "raw" string
These strings have no problems of their siblings in other languages:
- No need for any special termination symbol/sequence - it's done by indentation.
- Source code indentation is not included in the string.
- Additional indentation can be added in the string to help formatting the output.
- Line end encoding is controlled by developer. It doesn't depend on source code formatting. Make it CR, LF or any combinations.
- Extra indentation, can go in form of tabs or spaces, this is also under developer's control.
- Argentum also takes in account such peculiar details as last line endings and indentations.
More examples and details are here: multiline-string-constants
-
Interop with C/C++
05/08/2023 at 02:56 • 0 commentsArgentum can natively call C/C++ functions, pass primitives, objects and raw structures (with sys_Blob object). Example:
In C/C++
#include <stdio.h> #include "../argentum/src/runtime/runtime.h" bool ag_fn_io_writeFile(AgString* name, AgString* content) { FILE* f = fopen(name->ptr, "wb"); if (!f) return false; bool r = fputs(content->ptr, f) >= 0; fclose(f); return r; }
In Argentum (file io.ag):
using sys { String; log; } fn writeFile(name String, content String) bool; writeFile("1.txt", "File data") ? log("done")
More details are here: ffi-tutorial
-
Argentum got const objects and shared pointers
04/27/2023 at 17:18 • 0 commentsAnrgentum objects can be turned immutable with prefix freeze operator "*".
class Point { x = 0; y = 0; set(x int, y int) this { this.x := x; this.y := y; } } p = *Point.set(10, 42); // now point p is immutable p.x += 1; // compilation error, `p` is *Point, and cannot be modified.
Immutable objects are shared across object hierarchies and threads.
There can be declared a methods, specifically callable to immutable objects and methods that cam be called on any objects - regardless their mutable status:
class Node { name = ""; chilren = Array; -isLeaf() bool { children.size() == 0 } } // method `isLeaf` can be called on any Node - frozen or not
Frozen pointers can reference one object from different other objects. They represent the "aggregation" relationships in terms of UML. With adding of this mechanism Argentum now supports all UML object relations:
- Composition with unique "@pointers" to mutable objects
- Aggregation with shared "*pointers" to immutable objects
- Association with non owning "&pointers".
Details are here: http://aglang.org/.....shared-pointers-to-immutable-objects
-
Argentum objects got parent pointers and safe-n-fast object reattachments
04/27/2023 at 01:55 • 0 commentsEach object can tell who is its parent.
These parent pointer are maintained automatically at a very low cost (single move instruction).
This ability simplifies the handling of document data models and can facilitate integrity checks if needed.sys_getParent(existingObject)
Function sys_GetParent returns
- object in which field this object is located,
- or array object if it's in an array,
- or null if this object is not nested in another object.
Function result is ?sys_Object.
This parent pointers also assist a new "splice" operation, that allows to extract an existing object from one part of the object hierarchy and insert it in other place:
temp = object.field; // save the link to object stored somewhere object.field := newValue; // make it not stored there anymore // or object := newValue; // or destroy the hierarchy it belonged anotherParentObject.field @= temp // "splice" this object in another place.
This allows to reorganize object hierarchies in safe and effortless manner (previously it required a copy operation).
-
Improved modules and name resolution
04/18/2023 at 20:23 • 0 commentsToday Argentum got small but fundamental improvements:
- Names are isolated in modules.
- Explicit module dependencies.
- lightweight imports.
How it was previously (file `demo.ag`):
using sdl; using utils; using gui; class Scene{ +gui_Group; sdl = sdl_Sdl; w = sdl_Window; rnd = utils_Random; flare = sdl_Texture; star = sdl_Texture; background = sdl_Texture; foreground = sdl_Texture; ...
How it is now:
using sdl { Window, Sdl, Texture } using gui { Actor, Group } class Scene{ +Group; sdl = Sdl; w = Window; rnd = Random; flare = Texture; star = Texture; background = Texture; foreground = Texture;
Previously any compound names like `sdl_image_mySurface` were able to be created and used in any package. And they always had to be written in full.
Since now names should follow rule: `packageName_functionOrClassName` (for example: `sdlImage_mySurface` or from example above `demo_Scene`. And since names are bound to a module, no need to write them in that long form.
All names defined in a module `demo` are automatically `demo_*`.
When a module declares some dependency with the `using` directive, it may list all names to import and use in short form: `using gui { Actor; Group; }`
If names from different imports collide, give them aliases: `using gui { Control=Actor; }`
Now `Control` can be used instead of `gui_Actor`.TL;DR: Argentum names just got better.
More on names: link
New compiler and stdlib version: windows demo -
Fizz-Buzz.ag
04/11/2023 at 14:12 • 0 commentsThis is a working solution for the famous fizz-buzz coding interview question.
using string; using utils; b = string_Builder; forRange(1, 101, (i) { i % 3 == 0 ? b.putStr("fizz"); i % 5 == 0 ? b.putStr("buzz"); b.pos == 0 ? b.putInt(i); sys_log(b.newLine().toStr()); });
Details, explanations are in the tutorial: aglang.org/tutorial-1-fizz-buzz
How to install the compiler and configure VSCode: aglang.org/how-to-play-with-argentum-in-vscode
-
Project website - aglang.org
04/09/2023 at 18:55 • 0 commentsArgentum programming language got a website: https://aglang.org
- documentation,
- blog,
- downloads,
- tutorials,
- discussions etc.
All main announces will be dubbed at both Hackaday and AgLang.org
-
Windows Demo v0.0.0
04/07/2023 at 18:21 • 0 commentsI just released a demo that lets everyone to try the Argentum programming language on Windows.
Download link: argentum-demo.7z
It contains:
- a command line compiler,
- simple bindings to SDL,
- and a couple of examples.
Short instruction:
- download,
- extract anywhere,
- read the README.md,
- go to the workdir folder, and launch cmd.
- copy and paste these three commands to compile, link and execute the hello world application:
..\bin\agc.exe -src ..\src -start hello_world -o hw.obj ..\bin\lld-link.exe /libpath:..\libs hw.obj ..\libs\ag_runtime.lib hw.exe
Do the same for the SDL demo application:
..\bin\agc.exe -src ..\src -start demo -o demo.obj ..\bin\lld-link.exe /libpath:..\libs demo.obj ..\libs\ag_runtime.lib ..\libs\SDL2.lib ..\libs\SDL2_image.lib demo.exe
Play with `*.ag` files in `src` directory to see how the language works.
All my examples from the the ongoing posts will work with this compiler.
-
Why?
04/03/2023 at 22:28 • 0 commentsWhy do we need one more programming language?
All nowadays programming languages fall in three possible categories on controlling object lifetimes, memory management and maintaining data structures:
- Manual allocations and deallocations (C/C++...)
- Garbage collector (Go, Kotlin, Java, Python, Dart...)
- Semi-automatic ref counting (Swift, Rust, C++ with smart-pointers...)
All these three approaches have something in common. They all allow developers to create a mess out of data structures and then try to assist programmers more or less in handling that mess.
Argentum proposes the opposite approach. It allows programmers to explicitly declare ownership in cross-object references and automate all operations over data structures using these declarations. And these automatically provided operations guarantee that there are no dangling pointers, unsafe memory access or memory leaks.
Let's look at the example:
class Scene { // this field owns Array, which owns its elements. elements = Array(SceneItem); // this field just references an item, but doesn't own it. focused = &SceneItem; } class SceneItem { x = 0; y = 0; scene = &Scene; // `scene` field references its scene, but doesn't own it. } class Label { +SceneItem; // It's inheritance. text = ""; // `style` field shares ownership over an immutable `Style` instance. style = *Style; } // Create new mutable instance of Scene: root = Scene; // Create Style, fill it and freeze it (with *-operator), making it shareable: normal = *Style.font(times).size(40).weight(600); // Create new Label instance and attach it to the scene. root.elements.add( Label.at(10, 20).setText("Hello").setStyle(normal));
This code gives us a hierarchy of objects that are aware of their ownership and lifetimes.
The `Label` exists as long as it is referenced from the `root` scene. Root scene exists as long as it's referenced by the `root` variable. The `normal` Style exists as long as it's referenced by either label or `normal` variable.
We can destroy all these objects by assigning new values to the correspondent variables and array items.
scene.elements.delete(0);
We can copy any object or the whole scene
anotherScene = @scene; // @ - is a deep copy operator
And this copy will preserve all the properties of the original scene:
- Scene and all mutable subitems will be copied and connected accordingly,
- All non-owning pointers:
- that are inner to the copied hierarchy will be copied in a way to preserve the topology graph,
- pointing outside will pointing to the same objects as in the original,
- If some objects hold system resources (files, sockets, fonts...) the special handlers will be called to handle these resources,
- Argentum also maintains the correctness of `parent` pointers.
And this copy operation performed at the cost of actual objects allocation with no overheads both in space and time.
The same is true for other operations: objects removal, freezing, passing between threads. All these operations are performed automatically by `*` and `&` markers on object fields.
Thus, this language is for sure works differently than mentioned above three groups of all existing languages, that's why it needs to be implemented.