1
0

COLORを実�

This commit is contained in:
otya128
2015-07-11 22:21:48 +09:00
parent f10437449f
commit 7ad5c9ff3c
4 changed files with 167 additions and 28 deletions

View File

@@ -867,8 +867,18 @@ class CallBuiltinFunction : Code
} }
override void execute(VM vm) override void execute(VM vm)
{ {
Value[] arg = vm.stack[vm.stacki - argcount..vm.stacki]; Value[] arg;
Value[] result = vm.stack[vm.stacki - argcount..vm.stacki - argcount + outcount];//雑; Value[] result;
if(func.hasSkipArgument)
{
arg = vm.stack[vm.stacki - func.argments.length..vm.stacki];
result = vm.stack[vm.stacki - func.argments.length..vm.stacki - func.argments.length + outcount];//雑;
}
else
{
arg = vm.stack[vm.stacki - argcount..vm.stacki];
result = vm.stack[vm.stacki - argcount..vm.stacki - argcount + outcount];//雑;
}
func.func(vm.petitcomputer, arg, result); func.func(vm.petitcomputer, arg, result);
} }
} }

View File

@@ -11,7 +11,7 @@ import otya.smilebasic.type;
import otya.smilebasic.petitcomputer; import otya.smilebasic.petitcomputer;
//プチコンの引数省略は特殊なので //プチコンの引数省略は特殊なので
//LOCATE ,,0のように省略できる //LOCATE ,,0のように省略できる
struct DefaultValue(T) struct DefaultValue(T, bool skippable = true)
{ {
T value; T value;
bool isDefault; bool isDefault;
@@ -29,6 +29,11 @@ struct DefaultValue(T)
{ {
isDefault = f; isDefault = f;
} }
void setDefaultValue(T v)
{
if(isDefault)
value = v;
}
mixin Proxy!value; mixin Proxy!value;
} }
alias ValueType = otya.smilebasic.type.ValueType; alias ValueType = otya.smilebasic.type.ValueType;
@@ -36,17 +41,24 @@ struct BuiltinFunctionArgument
{ {
ValueType argType; ValueType argType;
bool optionalArg; bool optionalArg;
bool skipArg;
} }
class BuiltinFunction class BuiltinFunction
{ {
BuiltinFunctionArgument[] argments; BuiltinFunctionArgument[] argments;
ValueType result; ValueType result;
void function(PetitComputer, Value[], Value[]) func; void function(PetitComputer, Value[], Value[]) func;
this(BuiltinFunctionArgument[] argments, ValueType result, void function(PetitComputer, Value[], Value[]) func) int startskip;
this(BuiltinFunctionArgument[] argments, ValueType result, void function(PetitComputer, Value[], Value[]) func, int startskip)
{ {
this.argments = argments; this.argments = argments;
this.result = result; this.result = result;
this.func = func; this.func = func;
this.startskip = startskip;
}
bool hasSkipArgument()
{
return this.startskip != this.argments.length;
} }
import std.math; import std.math;
/* /*
@@ -56,8 +68,21 @@ class BuiltinFunction
}*/ }*/
static double function(double) ABS = &abs!double; static double function(double) ABS = &abs!double;
//static ABS = function double(double x) => abs(this.result == ValueType.Double ? 1 : 0); //static ABS = function double(double x) => abs(this.result == ValueType.Double ? 1 : 0);
static void LOCATE(PetitComputer p, DefaultValue!int x, DefaultValue!int y, DefaultValue!int z) static void LOCATE(PetitComputer p, DefaultValue!int x, DefaultValue!int y, DefaultValue!(int, false) z)
{ {
x.setDefaultValue(p.CSRX);
y.setDefaultValue(p.CSRY);
z.setDefaultValue(p.CSRZ);
p.CSRX = cast(int)x;
p.CSRY = cast(int)y;
p.CSRZ = cast(int)z;
}
static void COLOR(PetitComputer p, DefaultValue!int fore, DefaultValue!(int, false) back)
{
fore.setDefaultValue(p.consoleForeColor);
back.setDefaultValue(p.consoleBackColor);
p.consoleForeColor = cast(int)fore;
p.consoleBackColor = cast(int)back;
} }
//alias void function(PetitComputer, Value[], Value[]) BuiltinFunc; //alias void function(PetitComputer, Value[], Value[]) BuiltinFunc;
static BuiltinFunction[wstring] builtinFunctions; static BuiltinFunction[wstring] builtinFunctions;
@@ -71,7 +96,8 @@ class BuiltinFunction
builtinFunctions[name] = new BuiltinFunction( builtinFunctions[name] = new BuiltinFunction(
GetFunctionParamType!(BuiltinFunction, name), GetFunctionParamType!(BuiltinFunction, name),
GetFunctionReturnType!(BuiltinFunction, name), GetFunctionReturnType!(BuiltinFunction, name),
mixin(AddFunc!(BuiltinFunction, name)) mixin(AddFunc!(BuiltinFunction, name)),
GetStartSkip!(BuiltinFunction, name),
); );
writeln(AddFunc!(BuiltinFunction, name)); writeln(AddFunc!(BuiltinFunction, name));
} }
@@ -79,6 +105,25 @@ class BuiltinFunction
} }
} }
template GetStartSkip(T, string N)
{
private template SkipSkip(int I, P...)
{
static if(P.length <= I)
{
enum SkipSkip = I - is(P[0] == PetitComputer);
}
else static if(is(P[I] == DefaultValue!(int, false)))
{
enum SkipSkip = I - is(P[0] : PetitComputer);
}
else
{
enum SkipSkip = SkipSkip!(I + 1, P);
}
}
enum GetStartSkip = SkipSkip!(0, ParameterTypeTuple!(__traits(getMember, T, N)));
}
template GetFunctionReturnType(T, string N) template GetFunctionReturnType(T, string N)
{ {
static if(is(ReturnType!(__traits(getMember, T, N)) == double)) static if(is(ReturnType!(__traits(getMember, T, N)) == double))
@@ -100,12 +145,12 @@ template AddFunc(T, string N)
static if(is(ReturnType!(__traits(getMember, T, N)) == double)) static if(is(ReturnType!(__traits(getMember, T, N)) == double))
{ {
const string AddFunc = "function void(PetitComputer p, Value[] arg, Value[] ret){if(ret.length != 1){throw new IllegalFunctionCall();}ret[0] = Value(" ~ N ~ "(" ~ const string AddFunc = "function void(PetitComputer p, Value[] arg, Value[] ret){if(ret.length != 1){throw new IllegalFunctionCall();}ret[0] = Value(" ~ N ~ "(" ~
AddFuncArg!(0, 0, ParameterTypeTuple!(__traits(getMember, T, N))) ~ "));}"; AddFuncArg!(ParameterTypeTuple!(__traits(getMember, T, N)).length - 1, 0, 0, ParameterTypeTuple!(__traits(getMember, T, N))) ~ "));}";
} }
else static if(is(ReturnType!(__traits(getMember, T, N)) == void)) else static if(is(ReturnType!(__traits(getMember, T, N)) == void))
{ {
const string AddFunc = "function void(PetitComputer p, Value[] arg, Value[] ret){if(ret.length != 1){throw new IllegalFunctionCall();}" ~ N ~ "(" ~ const string AddFunc = "function void(PetitComputer p, Value[] arg, Value[] ret){if(ret.length != 0){throw new IllegalFunctionCall();}" ~ N ~ "(" ~
AddFuncArg!(0, 0, ParameterTypeTuple!(__traits(getMember, T, N))) ~ ");}"; AddFuncArg!(ParameterTypeTuple!(__traits(getMember, T, N)).length - 1, 0, 0, ParameterTypeTuple!(__traits(getMember, T, N))) ~ ");}";
} }
else else
{ {
@@ -120,6 +165,13 @@ DefaultValue!int fromIntToDefault(Value v)
else else
return DefaultValue!int(true); return DefaultValue!int(true);
} }
DefaultValue!(int, false) fromIntToSkip(Value v)
{
if(v.isNumber)
return DefaultValue!(int, false)(v.castInteger());
else
return DefaultValue!(int, false)(true);
}
template GetFunctionParamType(T, string N) template GetFunctionParamType(T, string N)
{ {
enum GetFunctionParamType = mixin("[" ~ Array!(ParameterTypeTuple!(__traits(getMember, T, N))) ~ "]"); enum GetFunctionParamType = mixin("[" ~ Array!(ParameterTypeTuple!(__traits(getMember, T, N))) ~ "]");
@@ -137,6 +189,10 @@ template GetFunctionParamType(T, string N)
{ {
const string arg = "ValueType.Integer, true"; const string arg = "ValueType.Integer, true";
} }
else static if(is(P[0] == DefaultValue!(int, false)))
{
const string arg = "ValueType.Integer, true";
}
else static if(is(P[0] == PetitComputer)) else static if(is(P[0] == PetitComputer))
{ {
enum Array = Array!(P[1..$]); enum Array = Array!(P[1..$]);
@@ -151,12 +207,13 @@ template GetFunctionParamType(T, string N)
} }
} }
} }
template AddFuncArg(int N, int M, P...) template AddFuncArg(int L, int N, int M, P...)
{ {
enum I = L - N;
static if(is(P[0] == double)) static if(is(P[0] == double))
{ {
enum add = 1; enum add = 1;
const string arg = "arg[" ~ N.to!string ~ "].castDouble"; const string arg = "arg[" ~ I.to!string ~ "].castDouble";
} }
else static if(is(P[0] == PetitComputer)) else static if(is(P[0] == PetitComputer))
{ {
@@ -166,12 +223,17 @@ template AddFuncArg(int N, int M, P...)
else static if(is(P[0] == int)) else static if(is(P[0] == int))
{ {
enum add = 1; enum add = 1;
const string arg = "arg[" ~ N.to!string ~ "].castInteger"; const string arg = "arg[" ~ I.to!string ~ "].castInteger";
} }
else static if(is(P[0] == DefaultValue!int)) else static if(is(P[0] == DefaultValue!int))
{ {
enum add = 1; enum add = 1;
const string arg = "fromIntToDefault(arg[" ~ N.to!string ~ "])"; const string arg = "fromIntToDefault(arg[" ~ I.to!string ~ "])";
}
else static if(is(P[0] == DefaultValue!(int, false)))
{
enum add = 1;
const string arg = "fromIntToSkip(arg[" ~ I.to!string ~ "])";
} }
else else
{ {
@@ -185,6 +247,6 @@ template AddFuncArg(int N, int M, P...)
} }
else else
{ {
const string AddFuncArg = arg ~ ", " ~ AddFuncArg!(N + add, M + 1, P[1..$]); const string AddFuncArg = arg ~ ", " ~ AddFuncArg!(L - !add, N + add, M + 1, P[1..$]);
} }
} }

View File

@@ -331,11 +331,19 @@ class Compiler
case NodeType.CallFunction: case NodeType.CallFunction:
{ {
auto func = cast(CallFunction)exp; auto func = cast(CallFunction)exp;
auto bfun = otya.smilebasic.builtinfunctions.BuiltinFunction.builtinFunctions.get(func.name, null);
if(bfun)
{
auto k = bfun.argments.length - func.args.length;
foreach(l;0..k)
{
genCodeImm(Value(ValueType.Void));
}
}
foreach_reverse(Expression i ; func.args) foreach_reverse(Expression i ; func.args)
{ {
compileExpression(i, sc); compileExpression(i, sc);
} }
auto bfun = otya.smilebasic.builtinfunctions.BuiltinFunction.builtinFunctions.get(func.name, null);
if(bfun) if(bfun)
{ {
genCode(new CallBuiltinFunction(bfun, func.args.length, 1)); genCode(new CallBuiltinFunction(bfun, func.args.length, 1));
@@ -602,11 +610,19 @@ class Compiler
case NodeType.CallFunctionStatement: case NodeType.CallFunctionStatement:
{ {
auto func = cast(CallFunctionStatement)i; auto func = cast(CallFunctionStatement)i;
auto bfun = otya.smilebasic.builtinfunctions.BuiltinFunction.builtinFunctions.get(func.name, null);
if(bfun)
{
auto k = bfun.argments.length - func.args.length;
foreach(l;0..k)
{
genCodeImm(Value(ValueType.Void));
}
}
foreach_reverse(Expression j ; func.args) foreach_reverse(Expression j ; func.args)
{ {
compileExpression(j, s); compileExpression(j, s);
} }
auto bfun = otya.smilebasic.builtinfunctions.BuiltinFunction.builtinFunctions.get(func.name, null);
if(bfun) if(bfun)
{ {
genCode(new CallBuiltinFunction(bfun, func.args.length, func.outVariable.length)); genCode(new CallBuiltinFunction(bfun, func.args.length, func.outVariable.length));

View File

@@ -39,7 +39,36 @@ class PetitComputer
int fontHeight; int fontHeight;
int consoleWidth; int consoleWidth;
int consoleHeight; int consoleHeight;
wchar[][] console; int[] consoleColor =
[
0x00000000,
0xFF000000,
0xFF7F0000,
0xFFFF0000,
0xFF007F00,
0xFF00FF00,
0xFF7F7F00,
0xFFFFFF00,
0xFF00007F,
0xFF0000FF,
0xFF7F007F,
0xFFFF00FF,
0xFF007F7F,
0xFF00FFFF,
0xFF7F7F7F,
0xFFFFFFFF,
];
struct ConsoleCharacter
{
wchar charater;
int foreColor;
int backColor;
}
SDL_Color PetitColor(byte r, byte g, byte b, byte a)
{
return SDL_Color(r >> 5 << 5, g >> 5 << 5, b >> 5 << 5, a == 255 ? 255 : 0);
}
ConsoleCharacter[][] console;
GraphicPage[] grp; GraphicPage[] grp;
GraphicPage GRPF; GraphicPage GRPF;
//PNG画像から透過色のpixelを指定して透過しGRPを作る //PNG画像から透過色のpixelを指定して透過しGRPを作る
@@ -158,12 +187,15 @@ class PetitComputer
fontHeight = 8; fontHeight = 8;
consoleWidth = screenWidth / fontWidth; consoleWidth = screenWidth / fontWidth;
consoleHeight = screenHeight / fontHeight; consoleHeight = screenHeight / fontHeight;
console = new wchar[][consoleHeight]; console = new ConsoleCharacter[][consoleHeight];
consoleForeColor = 15;//#T_WHITE
for(int i = 0; i < console.length; i++) for(int i = 0; i < console.length; i++)
{ {
console[i] = new wchar[consoleWidth]; console[i] = new ConsoleCharacter[consoleWidth];
console[i][] = ConsoleCharacter(0, consoleForeColor, consoleBackColor);
/*
for(int j = 0; j < console[i].length; j++) for(int j = 0; j < console[i].length; j++)
console[i][j] = '\0'; console[i][j] = '\0';*/
} }
} }
SDL_Renderer* renderer; SDL_Renderer* renderer;
@@ -177,15 +209,26 @@ class PetitComputer
renderer = SDL_CreateRenderer(window, -1, 0); renderer = SDL_CreateRenderer(window, -1, 0);
GRPF.createTexture(renderer); GRPF.createTexture(renderer);
//とりあえず //とりあえず
auto parser = new Parser(/*readText("FIZZBUZZ.TXT").to!wstring*/" auto parser = new Parser(/*readText("FIZZBUZZ.TXT").to!wstring*//*"
?ABS(-1) ?ABS(-1)
LOCATE 0,10
COLOR 5
FOR I=0 TO 10 FOR I=0 TO 10
?I;\"!\",\"=\",FACT(I) ?I;\"!\",\"=\",FACT(I)
NEXT NEXT
DEF FACT(N) DEF FACT(N)
IF N<=1 THEN RETURN 1 IF N<=1 THEN RETURN 1
RETURN N*FACT(N-1) RETURN N*FACT(N-1)
END"); END"*/
`CLS : CL=0 : Z=0
WHILE 1
INC Z : IF Z>200 THEN Z=0
FOR I=0 TO 15
LOCATE 9,4+I,Z : COLOR (CL+I) MOD 16
PRINT "★ 梅雨で雨が多い季節ですね ★"
NEXT
CL=(CL+1) MOD 16 : VSYNC 2
WEND`);
auto vm = parser.compile(); auto vm = parser.compile();
bool running = true; bool running = true;
vm.init(this); vm.init(this);
@@ -209,7 +252,7 @@ END");
catch catch
{ {
} }
}/* }
catch(Throwable t) catch(Throwable t)
{ {
running = false; running = false;
@@ -220,7 +263,7 @@ END");
catch catch
{ {
} }
}*/ }
elapse = SDL_GetTicks() - startTicks; elapse = SDL_GetTicks() - startTicks;
} while(elapse <= 1000 / 60); } while(elapse <= 1000 / 60);
SDL_Event event; SDL_Event event;
@@ -248,13 +291,20 @@ END");
int CSRX; int CSRX;
int CSRY; int CSRY;
int CSRZ; int CSRZ;
int consoleForeColor, consoleBackColor;
void renderConsole() void renderConsole()
{ {
for(int y = 0; y < consoleHeight; y++) for(int y = 0; y < consoleHeight; y++)
for(int x = 0; x < consoleWidth; x++) for(int x = 0; x < consoleWidth; x++)
{ {
SDL_Rect rect = SDL_Rect(x * 8, y * 8, 8, 8); SDL_Rect rect = SDL_Rect(x * 8, y * 8, 8, 8);
SDL_RenderCopy(renderer, GRPF.texture, &fontTable[console[y][x]], &rect); auto back = consoleColor[console[y][x].backColor];
SDL_SetRenderDrawColor(renderer, back >> 16 & 0xFF, back >> 8 & 0xFF, back & 0xFF, back >> 24 & 0xFF);
SDL_RenderFillRect(renderer, &rect);
auto fore = consoleColor[console[y][x].foreColor];
SDL_SetTextureColorMod(GRPF.texture, fore >> 16 & 0xFF, fore >> 8 & 0xFF, fore & 0xFF);
SDL_SetTextureAlphaMod(GRPF.texture, fore >> 24 & 0xFF);
SDL_RenderCopy(renderer, GRPF.texture, &fontTable[console[y][x].charater], &rect);
} }
} }
void printConsole(T...)(T args) void printConsole(T...)(T args)
@@ -274,7 +324,9 @@ END");
} }
if(c != '\r' && c != '\n') if(c != '\r' && c != '\n')
{ {
console[CSRY][CSRX] = c; console[CSRY][CSRX].charater = c;
console[CSRY][CSRX].foreColor = consoleForeColor;
console[CSRY][CSRX].backColor = consoleBackColor;
} }
CSRX++; CSRX++;
if(CSRX >= consoleWidth || c == '\n' || c == '\r') if(CSRX >= consoleWidth || c == '\n' || c == '\r')
@@ -290,8 +342,7 @@ END");
console[i] = console[i + 1]; console[i] = console[i + 1];
} }
console[consoleHeight - 1] = tmp; console[consoleHeight - 1] = tmp;
for(int j = 0; j < tmp.length; j++) tmp[] = ConsoleCharacter(0, consoleForeColor, consoleBackColor);
tmp[j] = '\0';
assert(console[0] != console[2]); assert(console[0] != console[2]);
CSRY = consoleHeight - 1; CSRY = consoleHeight - 1;
} }