Skip to content

Commit 938eea7

Browse files
committed
Builtin abs() (#458)
1 parent c16dc53 commit 938eea7

File tree

9 files changed

+36
-7
lines changed

9 files changed

+36
-7
lines changed

Umka.sublime-syntax

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ file_extensions:
55
- um
66
scope: source.umka
77
variables:
8-
builtin: (append|atan|atan2|cap|ceil|copy|cos|delete|exit|exp|fabs|floor|fprintf|fscanf|insert|keys|len|log|make|memusage|new|printf|resume|round|scanf|selfhasptr|selftypeeq|sin|sizeof|sizeofself|slice|sort|sprintf|sqrt|sscanf|trunc|typeptr|valid|validkey)
8+
builtin: (abs|append|atan|atan2|cap|ceil|copy|cos|delete|exit|exp|fabs|floor|fprintf|fscanf|insert|keys|len|log|make|memusage|new|printf|resume|round|scanf|selfhasptr|selftypeeq|sin|sizeof|sizeofself|slice|sort|sprintf|sqrt|sscanf|trunc|typeptr|valid|validkey)
99
ident: '[A-Za-z_][A-Za-z_0-9]*'
1010
typeident: '_*[A-Z][A-Za-z_0-9]*'
1111
space: '\s*'

doc/lang.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,7 @@ fn round(x: real): int // Rounding to the nearest integer
683683
fn trunc(x: real): int // Rounding towards zero
684684
fn ceil (x: real): int // Rounding upwards
685685
fn floor(x: real): int // Rounding downwards
686+
fn abs (x: int): int // Absolute value
686687
fn fabs (x: real): real // Absolute value
687688
fn sqrt (x: real): real // Square root
688689
fn sin (x: real): real // Sine

playground/umka.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/umka_compiler.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ static void compilerDeclareBuiltinIdents(Compiler *comp)
128128
identAddBuiltinFunc(&comp->idents, &comp->modules, &comp->blocks, "trunc", comp->intType, BUILTIN_TRUNC);
129129
identAddBuiltinFunc(&comp->idents, &comp->modules, &comp->blocks, "ceil", comp->intType, BUILTIN_CEIL);
130130
identAddBuiltinFunc(&comp->idents, &comp->modules, &comp->blocks, "floor", comp->intType, BUILTIN_FLOOR);
131+
identAddBuiltinFunc(&comp->idents, &comp->modules, &comp->blocks, "abs", comp->intType, BUILTIN_ABS);
131132
identAddBuiltinFunc(&comp->idents, &comp->modules, &comp->blocks, "fabs", comp->realType, BUILTIN_FABS);
132133
identAddBuiltinFunc(&comp->idents, &comp->modules, &comp->blocks, "sqrt", comp->realType, BUILTIN_SQRT);
133134
identAddBuiltinFunc(&comp->idents, &comp->modules, &comp->blocks, "sin", comp->realType, BUILTIN_SIN);

src/umka_const.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <string.h>
55
#include <limits.h>
66
#include <math.h>
7+
#include <inttypes.h>
78

89
#include "umka_const.h"
910

@@ -230,6 +231,13 @@ void constCallBuiltin(Consts *consts, Const *arg, const Const *arg2, TypeKind ar
230231
case BUILTIN_TRUNC: arg->intVal = (int64_t)trunc(arg->realVal); break;
231232
case BUILTIN_CEIL: arg->intVal = (int64_t)ceil (arg->realVal); break;
232233
case BUILTIN_FLOOR: arg->intVal = (int64_t)floor(arg->realVal); break;
234+
case BUILTIN_ABS:
235+
{
236+
if (arg->intVal == LLONG_MIN)
237+
consts->error->handler(consts->error->context, "abs() domain error");
238+
arg->intVal = llabs(arg->intVal);
239+
break;
240+
}
233241
case BUILTIN_FABS: arg->realVal = fabs(arg->realVal); break;
234242
case BUILTIN_SQRT:
235243
{

src/umka_expr.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -833,9 +833,11 @@ static void parseBuiltinIOCall(Compiler *comp, Type **type, Const *constant, Bui
833833

834834
static void parseBuiltinMathCall(Compiler *comp, Type **type, Const *constant, BuiltinFunc builtin)
835835
{
836-
*type = comp->realType;
836+
Type *argType = (builtin == BUILTIN_ABS) ? comp->intType : comp->realType;
837+
838+
*type = argType;
837839
parseExpr(comp, type, constant);
838-
doAssertImplicitTypeConv(comp, comp->realType, type, constant);
840+
doAssertImplicitTypeConv(comp, argType, type, constant);
839841

840842
Const constant2Val = {.realVal = 0};
841843
Const *constant2 = NULL;
@@ -854,11 +856,11 @@ static void parseBuiltinMathCall(Compiler *comp, Type **type, Const *constant, B
854856
}
855857

856858
if (constant)
857-
constCallBuiltin(&comp->consts, constant, constant2, TYPE_REAL, builtin);
859+
constCallBuiltin(&comp->consts, constant, constant2, argType->kind, builtin);
858860
else
859-
genCallBuiltin(&comp->gen, TYPE_REAL, builtin);
861+
genCallBuiltin(&comp->gen, argType->kind, builtin);
860862

861-
if (builtin == BUILTIN_ROUND || builtin == BUILTIN_TRUNC || builtin == BUILTIN_CEIL || builtin == BUILTIN_FLOOR)
863+
if (builtin == BUILTIN_ROUND || builtin == BUILTIN_TRUNC || builtin == BUILTIN_CEIL || builtin == BUILTIN_FLOOR || builtin == BUILTIN_ABS)
862864
*type = comp->intType;
863865
else
864866
*type = comp->realType;
@@ -1515,6 +1517,7 @@ static void parseBuiltinCall(Compiler *comp, Type **type, Const *constant, Built
15151517
case BUILTIN_TRUNC:
15161518
case BUILTIN_CEIL:
15171519
case BUILTIN_FLOOR:
1520+
case BUILTIN_ABS:
15181521
case BUILTIN_FABS:
15191522
case BUILTIN_SQRT:
15201523
case BUILTIN_SIN:

src/umka_gen.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,12 @@ static bool optimizeCallBuiltin(CodeGen *gen, TypeKind typeKind, BuiltinFunc bui
388388
}
389389
break;
390390
}
391+
case BUILTIN_ABS:
392+
{
393+
arg.intVal = prev->operand.intVal;
394+
resultTypeKind = TYPE_INT;
395+
break;
396+
}
391397
case BUILTIN_ROUND:
392398
case BUILTIN_TRUNC:
393399
case BUILTIN_CEIL:

src/umka_vm.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <math.h>
2020
#include <limits.h>
2121
#include <ctype.h>
22+
#include <inttypes.h>
2223

2324
#include "umka_vm.h"
2425

@@ -112,6 +113,7 @@ static const char *builtinSpelling [] =
112113
"trunc",
113114
"ceil",
114115
"floor",
116+
"abs",
115117
"fabs",
116118
"sqrt",
117119
"sin",
@@ -3550,6 +3552,13 @@ static FORCE_INLINE void doCallBuiltin(Fiber *fiber, Fiber **newFiber, HeapPages
35503552
case BUILTIN_TRUNC: fiber->top->intVal = (int64_t)trunc(fiber->top->realVal); break;
35513553
case BUILTIN_CEIL: fiber->top->intVal = (int64_t)ceil (fiber->top->realVal); break;
35523554
case BUILTIN_FLOOR: fiber->top->intVal = (int64_t)floor(fiber->top->realVal); break;
3555+
case BUILTIN_ABS:
3556+
{
3557+
if (fiber->top->intVal == LLONG_MIN)
3558+
error->runtimeHandler(error->context, ERR_RUNTIME, "abs() domain error");
3559+
fiber->top->intVal = llabs(fiber->top->intVal);
3560+
break;
3561+
}
35533562
case BUILTIN_FABS: fiber->top->realVal = fabs(fiber->top->realVal); break;
35543563
case BUILTIN_SQRT:
35553564
{

src/umka_vm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ typedef enum
102102
BUILTIN_TRUNC,
103103
BUILTIN_CEIL,
104104
BUILTIN_FLOOR,
105+
BUILTIN_ABS,
105106
BUILTIN_FABS,
106107
BUILTIN_SQRT,
107108
BUILTIN_SIN,

0 commit comments

Comments
 (0)