Skip to content

Instantly share code, notes, and snippets.

@Hamayama
Last active April 22, 2023 06:59
Show Gist options
  • Save Hamayama/2f324852ec2bed3f471f8e986830c9ca to your computer and use it in GitHub Desktop.
Save Hamayama/2f324852ec2bed3f471f8e986830c9ca to your computer and use it in GitHub Desktop.
Gauche による C のコード生成のサンプル
gosh 1000_make_code.scm
pause
(use gauche.sequence)
(use util.match)
;; file encoding
(define *file-encoding* "utf-8")
;; make newline to crlf
(define *crlf* "\r\n")
(define (newline :optional (port (current-output-port))) (display *crlf* port))
(define (print . args) (for-each display args) (newline))
;; ===== data =====
(define *data*
#(
#(Parameter4 bool)
#(Parameter5 int)
#(Parameter6 float)
#(Parameter7 double)
))
;; ===== function =====
(define (get-one-data one-data)
(define name (x->string (vector-ref one-data 0)))
(define type (x->string (vector-ref one-data 1)))
(values name type))
(define (write-data-1)
(print "// (setting.c の「設定データ構造体」用の生成コード)")
(for-each
(lambda (one-data)
(receive (name type) (get-one-data one-data)
(format #t " ~6a ~a;" type name)
(newline)
))
*data*)
)
(define (write-data-2)
(print "// (setting.c の「キーテーブル」用の生成コード)")
(for-each
(lambda (one-data)
(receive (name type) (get-one-data one-data)
(print #" \"~|name|\",")
))
*data*)
)
(define (write-data-3)
(print "// (setting.c の「値を構造体に格納」用の生成コード)")
(for-each
(lambda (one-data)
(receive (name type) (get-one-data one-data)
(match type
("bool"
(print #" settingDataPtr->~|name| = (atoi(valueTable[count]) != 0); count++;"))
("int"
(print #" settingDataPtr->~|name| = atoi(valueTable[count]); count++;"))
("float"
(print #" settingDataPtr->~|name| = (float)atof(valueTable[count]); count++;"))
("double"
(print #" settingDataPtr->~|name| = atof(valueTable[count]); count++;"))
(_
(print #"// (~|name| is unknown type)")))
))
*data*)
)
(define (write-data-4)
(print "// (setting.c の「設定データ表示」用の生成コード)")
(for-each
(lambda (one-data)
(receive (name type) (get-one-data one-data)
(match type
("bool"
(print #" printf(\" ~|name|=%d\\n\", (int)SettingData1.~|name|);"))
("int"
(print #" printf(\" ~|name|=%d\\n\", SettingData1.~|name|);"))
("float"
(print #" printf(\" ~|name|=%g\\n\", SettingData1.~|name|);"))
("double"
(print #" printf(\" ~|name|=%g\\n\", SettingData1.~|name|);"))
(_
(print #"// (~|name| is unknown type)")))
))
*data*)
)
(define (write-data-5)
(print "// (settingData.txt の設定データ)")
(for-each
(lambda (one-data)
(receive (name type) (get-one-data one-data)
(print #"~|name|=")
))
*data*)
)
;; ===== main =====
(define (main args)
(with-output-to-file "9000_result_code_0001_typedef.txt"
(lambda ()
(write-data-1))
:encoding *file-encoding*)
(with-output-to-file "9000_result_code_0002_keytable.txt"
(lambda ()
(write-data-2))
:encoding *file-encoding*)
(with-output-to-file "9000_result_code_0003_set.txt"
(lambda ()
(write-data-3))
:encoding *file-encoding*)
(with-output-to-file "9000_result_code_0004_print.txt"
(lambda ()
(write-data-4))
:encoding *file-encoding*)
(with-output-to-file "9000_result_code_0005_settingData.txt"
(lambda ()
(write-data-5))
:encoding *file-encoding*)
)
@set PATH=C:\msys64\mingw64\bin;C:\msys64\usr\local\bin;C:\msys64\usr\bin;C:\msys64\bin;%PATH%
set MSYSTEM=MINGW64
for %%i in (
setting
) do (
gcc -g -O2 -Wall -Wextra -o %%i.exe %%i.c
)
pause
@rem set PATH=C:\msys64\mingw64\bin;C:\msys64\usr\local\bin;C:\msys64\usr\bin;C:\msys64\bin;%PATH%
@rem set MSYSTEM=MINGW64
@rem gdb setting.exe
setting.exe
pause
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
// 設定ファイル
#define SETTING_FILE "settingData.txt"
// 設定データ構造体
typedef struct {
bool IsUseFunctionA;
int Parameter1;
float Parameter2;
double Parameter3;
} SettingData;
// 設定データ
SettingData SettingData1;
// 行バッファサイズ
#define LINE_BUF_SIZE 1000
// 設定ファイル読み込み
// 戻り値 0 : 正常
// -1 : ファイルオープンエラー
// -2 : ファイルフォーマットエラー
int LoadSettingFile(const char *filePath, SettingData *settingDataPtr)
{
printf("ReadSettingFile()\n");
printf(" filePath=%s\n", filePath);
// キーテーブル
const char *keyTable[] =
{
"IsUseFunctionA",
"Parameter1",
"Parameter2",
"Parameter3",
};
const int keyTableSize = sizeof(keyTable) / sizeof(keyTable[0]);
printf(" keyTableSize=%d\n", keyTableSize);
// 値テーブル
char valueTable[keyTableSize][LINE_BUF_SIZE];
// 値の存在チェック用フラグ
bool valueExistsTable[keyTableSize];
for (int i = 0; i < keyTableSize; i++) { valueExistsTable[i] = false; }
// ファイルオープン
FILE *file;
file = fopen(filePath, "r");
if (file == NULL) { return -1; }
// ファイル読み込み
char buf[LINE_BUF_SIZE];
while (fgets(buf, LINE_BUF_SIZE, file) != NULL)
{
// 改行を削除
char *p1 = strchr(buf, '\n');
if (p1 != NULL) { *p1 = '\0'; }
printf(" %s\n", buf);
// コメント行をスキップ
if (buf[0] == ';') { continue; }
// キーと値に分離
char *p2 = strchr(buf, '=');
if (p2 == NULL) { continue; }
*p2 = '\0';
char *key = buf;
char *value = p2 + 1;
// キーに対応する値を取得
for (int i = 0; i < keyTableSize; i++)
{
if (strcmp(key, keyTable[i]) == 0)
{
strcpy(valueTable[i], value);
valueExistsTable[i] = true;
printf(" key=%s, value=%s\n", key, value);
}
}
}
// ファイルクローズ
fclose(file);
// 値の存在をチェック
for (int i = 0; i < keyTableSize; i++)
{
if (!valueExistsTable[i]) { return -2; }
}
// 値を構造体に格納
int count = 0;
settingDataPtr->IsUseFunctionA = (atoi(valueTable[count]) != 0); count++;
settingDataPtr->Parameter1 = atoi(valueTable[count]); count++;
settingDataPtr->Parameter2 = (float)atof(valueTable[count]); count++;
settingDataPtr->Parameter3 = atof(valueTable[count]); count++;
return 0;
}
// メイン処理
// 戻り値 0 : 正常
// 1 : エラー
int main(void)
{
// 設定ファイル読み込み
int ret = LoadSettingFile(SETTING_FILE, &SettingData1);
if (ret < 0)
{
printf("Setting file load error! (ret=%d)\n", ret);
return 1;
}
// 設定データ表示
printf("\n");
printf("SettingData1\n");
printf(" IsUseFunctionA=%d\n", (int)SettingData1.IsUseFunctionA);
printf(" Parameter1=%d\n", SettingData1.Parameter1);
printf(" Parameter2=%g\n", SettingData1.Parameter2);
printf(" Parameter3=%g\n", SettingData1.Parameter3);
return 0;
}
;; Setting data
IsUseFunctionA=1
Parameter1=12345
Parameter2=1.2345
Parameter3=1.2345e-10
Parameter4=6000
Parameter5=7000
Parameter6=8000
Parameter7=9000
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment